Milking Grid

poj2185:http://poj.org/problem?id=2185

题意:在一个字符矩阵中,找一个最小的字符子矩阵,使其能够覆盖整个矩阵。

题解:在KMP中i-next[i]是这能够覆盖这个串的最小串长度。所以这一题可以用KMP搞。对于每一行求一个最小覆盖,然后取其最小公倍数,如果最大的那个覆盖的2倍不小于串的的长度,那么此时应该取这个长度。然后列也是这个处理,最后把两个数乘起来就是要找的面积。

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 #define N 10005
 7 using namespace std;
 8 int  next[N];
 9 int n,m;
10 char s1[N];//模板串
11 char s2[N];//主串
12 int len1,len2;
13 int ans1,ans2;
14 char str1[N][80];
15 void getnext(int plen){
16     int i = 0,j = -1;
17     next[0]=-1;
18     while( i<plen ){
19         if(j==-1||s1[i]==s1[j]){
20             ++i;++j;
21          // if(s1[i]!=s1[j] )
22             next[i] = j;
23          // else
24           //  next[i] = next[j];
25         }
26         else
27             j = next[j];
28     }
29 }
30 int gcd(int a, int  b){
31     if(b==0)
32         return a;
33     return gcd(b,a%b);
34 }
35 
36 
37 int lcm(int  a, int  b){//两个数的最小公倍数
38    return a*b/gcd(a, b);
39 }
40 int main(){
41    while(~scanf("%d%d",&n,&m)){
42         ans1=1;
43         ans2=1;
44         int maxn=0;
45        for(int i=1;i<=n;i++){
46         scanf("%s",s1);
47         strcpy(str1[i],s1);
48         getnext(m);
49        // printf("**%d
",m-next[m]);
50          maxn=max(maxn,m-next[m]);
51        ans1=lcm(ans1,m-next[m]);
52        }
53        for(int i=0;i<m;i++){
54           for(int j=1;j<=n;j++){
55             s1[j-1]=str1[j][i];
56           }
57              getnext(n);
58 
59          ans2=lcm(ans2,n-next[n]);
60        }
61        if(maxn*2>=m)ans1=maxn;
62        else if(ans1>m)ans1=m;
63        if(ans2>n)ans2=n;
64        printf("%d
",ans1*ans2);
65    }
66 }
View Code
原文地址:https://www.cnblogs.com/chujian123/p/3859726.html