题目:http://poj.org/problem?id=2185
求出最小重复子矩阵的面积。我们知道,一个字符串的最小重复子串长度等于length-next[length],把所有行的最小值不断lcm,就能得到所有最小值的公倍数,也即是w。同理对列进行相应的操作就能得到h。另外由于可以有重叠部分超出原矩阵,所以w=min(w,c),h=min(h,r)。
#include <iostream>
#include<cstdio>
using namespace std;
const int maxn1=1e4+5,maxn2=80;
char s[maxn1][maxn2];
int snext[maxn1],r,c;
int getrs(int ri){
int i=0,j=-1;
snext[0]=-1;
while(i<=c){
if(j==-1||s[ri][i]==s[ri][j])snext[++i]=++j;
else j=snext[j];
}
return c-snext[c];
}
int getcs(int ci){
int i=0,j=-1;
snext[0]=-1;
while(i<=r){
if(j==-1||s[i][ci]==s[j][ci])snext[++i]=++j;
else j=snext[j];
}
return r-snext[r];
}
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
int lcm(int a,int b){
return a/gcd(a,b)*b;
}
int main()
{
//freopen("cin.txt","r",stdin);
while(cin>>r>>c){
int i,j,w=1,h=1;
for(i=0;i<r;i++){
scanf("%s",s[i]);
w=lcm(w,getrs(i));
}
for(j=0;j<c;j++){
h=lcm(h,getcs(j));
}
w=w<c?w:c;
h=h<r?h:r;
printf("%d\n",w*h);
}
return 0;
}