这个题关键要用到一个结论:最小覆盖子串(串尾多一小段时,用前缀覆盖)长度为n-next[n](n-pre[n]),n为串长。
论证见这篇博客:http://blog.youkuaiyun.com/fjsd155/article/details/6866991
其他的就没什么好说的了
code:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
char mp[10010][80];
int col,row;
int next[10010];
int getrow(int r)
{
int i=0,j=-1;
next[0] = -1;
while(i<col)
{
if(j == -1 || mp[r][i] == mp[r][j])next[++i] = ++j;
else j = next[j];
}
return i-next[i];
}
int getcol(int c)
{
int i=0,j=-1;
next[0] = -1;
while(i<row)
{
if(j == -1 || mp[i][c] == mp[j][c])next[++i] = ++j;
else j = next[j];
}
return i-next[i];
}
int gcd(int a,int b)
{
return b == 0 ? a:gcd(b,a%b);
}
int lcm(int a,int b)
{
return a/gcd(a,b)*b;
}
int main()
{
//freopen("input.txt","r",stdin);
while(~scanf("%d%d",&row,&col))
{
for(int i=0;i<row;i++)
scanf("%s",mp[i]);
//for(int i=0;i<row;i++)cout << mp[i] << endl;
int x = 1,y = 1;
for(int i=0;i<row;i++)
x = lcm(x,getrow(i));
for(int i=0;i<col;i++)
y = lcm(y,getcol(i));
if(x > col)x = col;
if(y > row)y = row;
printf("%d\n",x*y);
}
return 0;
}