题目大意:有一个R×C规模的字符矩阵,求出最小的子矩阵,使该矩阵可以由子矩阵平移得到,输出子矩阵的大小。
分析:很明显,符合条件的子矩阵(设该矩阵的规模为w×h)需要同时满足:
(1)该子矩阵的h行可以看成h个字符串,原矩阵中任一行字符串都可以由这h个字符串中的一个平铺形成;
(2)该子矩阵的w列也可以看成w个字符串,原矩阵中任一列字符串也都可以由这w个字符串中的一个平铺而成;
这样问题就很简单了:我们只需要分别找出原矩阵中的R个行字符串中,每个字符串所对应循环节中的最大的一个就是我们要找的w值;然后再在C个列字符串中,同理找出h值就可以了。
实现代码如下:
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
#define maxn 10010
char maze[maxn][80];
int next[maxn];
int r,c;
int get_nextc(int cnt)
{
int i=0,j=-1;
next[0]=-1;
while(i<c)
{
if(j==-1||maze[cnt][i]==maze[cnt][j])
{
i++;
j++;
next[i]=j;
}
else j=next[j];
}
return c-next[c];
}
int get_nextr(int cnt)
{
int i=0,j=-1;
next[0]=-1;
while(i<r)
{
if(j==-1||maze[i][cnt]==maze[j][cnt])
{
i++;
j++;
next[i]=j;
}
else j=next[j];
}
return r-next[r];
}
int main()
{
while(scanf("%d%d",&r,&c)!=-1)
{
for(int i=0;i<r;i++)
scanf("%s",maze[i]);
int w=0,h=0;
for(int i=0;i<r;i++)
w=max(w,get_nextc(i));
for(int i=0;i<c;i++)
h=max(h,get_nextr(i));
printf("%d\n",w*h);
}
return 0;
}