input:
2 5
ABABA
ABABA
output:
2
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
char str[10005][80];
int nex[10010];
int Row[10010];
int Col[80];//注意数组的范围!
int n,m;
int gcd(int a,int b);
int Rnex(int r);
int Cnex(int c);
int main()
{
int i,j;
int minc,minr;
while(scanf("%d %d",&n,&m)!=EOF)
{
memset(Col,0,sizeof Col);
memset(Row,0,sizeof Row);
for(i=1;i<=n;i++)
scanf("%s",str[i]+1);
for(int i=1;i<=n;i++)
Row[i]=Rnex(i);//每行对应的nex[len]
for(int i=1;i<=m;i++)
Col[i]=Cnex(i);//每列对应的nex[len]//我当时错的位置
minr=1;
for(int i=1;i<=n;i++)
minr=(minr*Row[i])/gcd(minr,Row[i]);//每行对应的最小公倍数
if(minr>m) minr=m;//最小公倍数超出列,则minr=列
minc=1;
for(int i=1;i<=m;i++)
minc=(minc*Col[i])/gcd(minc,Col[i]);//每列对应的最小公倍数
if(minc>n) minc=n;//最小公倍数超出行,则minc=行
printf("%d\n",minc*minr);
}
}
int gcd(int a,int b)
{
return a%b==0?b:gcd(b,a%b);//求最大公约数
}
int Rnex(int r)
{
memset(nex,0,sizeof nex);
int j=0;
nex[1]=j=0;
for(int i=2;i<=m;i++)
{
while(j&&str[r][j+1]!=str[r][i]) j=nex[j];
if(str[r][j+1]==str[r][i]) j++;
nex[i]=j;
}
return m-nex[m];
}
int Cnex(int c)
{
memset(nex,0,sizeof nex);
int j=0;
nex[1]=j=0;
for(int i=2;i<=n;i++)
{
while(j&&str[j+1][c]!=str[i][c]) j=nex[j];
if(str[j+1][c]==str[i][c]) j++;
nex[i]=j;
}
return n-nex[n];
}
//我翻车的原因,竟然是一个字母写错了!!太低级!下次不要这样!