Description
n*m的字符串,问用最小的面积的字符串去覆盖它,求最小的面积
Input
第一行为矩阵行列数n和m,之后为以n*m的矩阵
Output
输出最小覆盖矩阵的面积
Sample Input
2 5
ABABA
ABABA
Sample Output
2
Solution
可以分行分列考虑,容易想到当只考虑行的时候,只要把每一行看成一个字符,就可以求出关于行的next数组,然后求出最短的循环串 n-next[n],列也是如此,所以最终答案就是(n-next1[n])*)(m-next2[m]),next1,next2分别为行列的next数组
Code
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define maxn 11111
char s[maxn][maxn];
char c[maxn][maxn];
int next1[maxn];
int next2[maxn];
int n,m;
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=0;i<n;i++)
scanf("%s",s[i]);
int i,j;
for(i=0;i<n;i++)//c为s的转置矩阵
{
for(j=0;j<m;j++)
c[j][i]=s[i][j];
c[j][i]='\0';
}
next1[0]=next2[0]=-1;
for(int i=0,j=-1;i<n;)//求行的next数组
{
if(j==-1||strcmp(s[i],s[j])==0)
i++,j++,next1[i]=j;
else
j=next1[j];
}
for(int i=0,j=-1;i<m;)//求列的next数组
{
if(j==-1||strcmp(c[i],c[j])==0)
i++,j++,next2[i]=j;
else
j=next2[j];
}
printf("%d\n",(n-next1[n])*(m-next2[m]));
}
return 0;
}