题意:给定一个字符的矩阵,求一个最小大小的矩阵能够平铺变成整个矩阵。
思路:设一个字符串中最小的重复字符串长度为L/n,n为重复次数,则next[len],len为字符串最后一位,next[len]=L-L/n。
然后我们可以把一整列当成一个字符按行求next,再把一整行当一个字符按列求next。
(r-next[r])*(c-next[c])就是答案了。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define PI acos(-1)
#define INF 0x3f3f3f3f
#define NUM 256
#define debug true
#define ll long long
#define lowbit(x) ((-x)&x)
#define ffor(i,d,u) for(int i=d;i<=u;++i)
#define _ffor(i,u,d) for(int i=u;i>=d;--i)
#define mst(array,Num) memset(array,Num,sizeof(array))
const int p = 1e9+7;
int r,c,_next[10100];
char s1[10100][80],s2[80][10100];
template <typename T>
void read(T& x)
{
x=0;
char c;T t=1;
while(((c=getchar())<'0'||c>'9')&&c!='-');
if(c=='-'){t=-1;c=getchar();}
do(x*=10)+=(c-'0');while((c=getchar())>='0'&&c<='9');
x*=t;
}
template <typename T>
void write(T x)
{
int len=0;char c[21];
if(x<0)putchar('-'),x*=(-1);
do{++len;c[len]=(x%10)+'0';}while(x/=10);
_ffor(i,len,1)putchar(c[i]);
}
int getnextr(int x)
{
int i=_next[x];
while(i!=-1&&strcmp(s1[i],s1[x])!=0)i=_next[i];
return i+1;
}
int getnextc(int x)
{
int i=_next[x];
while(i!=-1&&strcmp(s2[i],s2[x])!=0)i=_next[i];
return i+1;
}
void AC()
{
int ans;
_next[0]=-1;_next[1]=0;
while(scanf("%d%d",&r,&c)!=EOF)
{
mst(s2,0);
ffor(i,0,r-1)
scanf("%s",s1[i]);
ffor(i,1,r-1)
_next[i+1]=getnextr(i);
ans=r-_next[r];
ffor(i,0,r-1)//转置矩阵
ffor(j,0,c-1)
s2[j][i]=s1[i][j];
ffor(i,1,c-1)
_next[i+1]=getnextc(i);
printf("%d\n",ans*(c-_next[c]));
}
}
int main()
{
AC();
return 0;
}