poj 2185

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

题意:求最小的模式块,使其无限扩展后包含给你的矩阵块(看别人题解才懂的题意);

分析:假设存在一个模式块可以满足上述条件,那么必然存在一个起点在(0,0)的模式块满足上述条件;

  对于每一行,我们找出所有可以满足条件的前缀记录下长度,那么满足所有行的最短的长度就是该模式块的宽r;

  对于模式块的长,我们把宽r的字符串压缩看出一个字符,然后再进行KMP,找出该字符串的最小循环串,即长l;

答案就是r * l;

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<vector>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<cmath>
 8 #include<cstdlib>
 9 using namespace std;
10 const int N = 10000+10;
11 int f[N];
12 void getFail(char *s,int f[]) {
13     int m = strlen(s);
14     f[0] = -1;
15     for (int i = 1; i < m; i++) {
16         int j = f[i-1];
17         while (j != -1 && s[j+1] != s[i]) j = f[j];
18         if (s[j+1] == s[i]) j++;
19         f[i] = j;
20     }
21  //   for (int i = 0; i < m; i++) cout<<f[i]<<" ";cout<<endl;
22 }
23 int n,m;
24 char mz[N][80];
25 int cnt[N];
26 int check(char *s,int x) {
27     int j = 0;
28     for (int i = 0; i < m; i++) {
29         if (s[i] != s[j]) return 0;
30         j++;
31         if (j > x) j = 0;
32     }
33     return 1;
34 }
35 void solve(int r){
36     f[0] = -1;
37     for (int i = 1; i < n; i++) {
38         int j = f[i-1];
39         while (j != -1 && strcmp(mz[j+1],mz[i])) j = f[j];
40         if (strcmp(mz[j+1],mz[i]) == 0) j++;
41         f[i] = j;
42     }
43    // for (int i = 0; i < n; i++) cout<<f[i]<<" ";cout<<endl;
44     printf("%d\n",(n - 1 - f[n-1]) * (r));
45 }
46 int main(){
47  //   getFail("ababab",f);
48     while (~scanf("%d%d",&n,&m)) {
49         memset(cnt,0,sizeof(cnt));
50 
51         for (int i = 0; i < n; i++) {
52             scanf("%s",mz[i]);
53             getFail(mz[i],f);
54             int j = m-1;
55             while (j != -1) {
56               //  cout<<m - 1 - f[j]<<endl;
57                 cnt[m - 1 - f[j]]++;
58                 j = f[j];
59             }
60         }
61         int r = 0;
62         for (int i = 1; i <= m; i++) if (cnt[i] == n) {
63             r = i; break;
64         }
65         for (int i = 0; i < n; i++) {
66             mz[i][r] = 0;
67         }
68 
69         solve(r);
70     }
71     return 0;
72 }
View Code

 

posted @ 2013-12-04 21:52  Rabbit_hair  阅读(733)  评论(0编辑  收藏  举报