题意:
在给定的矩形字符串中找一个最小的矩形字符串,使其通过多次平移复制后,覆盖给定的矩形字符串
题解:
网上的神马求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 }