POJ 2185 KMP

题意:

在给定的矩形字符串中找一个最小的矩形字符串,使其通过多次平移复制后,覆盖给定的矩形字符串

题解:

网上的神马求lcm的算法都是不完善的,具体解释见POJ 2185的discuss。。

我的做法是把行看成一个整体,列看成一个整体做kmp。

能过discuss里的数据,poj也ac了,不知道有没有漏洞。。感觉应该是对的。

View Code
 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <algorithm>
 6 
 7 using namespace std;
 8 
 9 char map[10010][80];
10 int n,m,next[10010];
11 
12 inline void read()
13 {
14     for(int i=1;i<=n;i++)
15        scanf("%s",map[i]+1);
16 }
17 
18 inline bool checkc(int x,int y)
19 {
20     for(int i=1;i<=n;i++)
21         if(map[i][x]!=map[i][y]) return false;
22     return true;
23 }
24 
25 inline bool checkr(int x,int y)
26 {
27     for(int i=1;i<=m;i++)
28         if(map[x][i]!=map[y][i]) return false;
29     return true;
30 }
31 
32 inline int getnexth()
33 {
34     next[1]=0;
35     for(int i=2,len=0;i<=m;i++)
36     {
37         while(len>0&&!checkc(i,len+1)) len=next[len];
38         if(checkc(i,len+1)) len++;
39         next[i]=len;
40     }
41     return m-next[m];
42 }
43 
44 inline int getnextl()
45 {
46     next[1]=0;
47     for(int i=2,len=0;i<=n;i++)
48     {
49         while(len>0&&!checkr(i,len+1)) len=next[len];
50         if(checkr(i,len+1)) len++;
51         next[i]=len;
52     }
53     return n-next[n]; 
54 }
55 
56 inline void go()
57 {
58     printf("%d\n",getnexth()*getnextl());
59 }
60 
61 int main()
62 {
63     while(scanf("%d%d",&n,&m)!=EOF) read(),go();
64     return 0;
65 }
原文地址:https://www.cnblogs.com/proverbs/p/2892748.html