纯纯的好题。
完美循环节的意思在141. 周期 - AcWing题库这道题里面有。
拥有完美循环节:abcabcabc
没有完美循环节:abcabcab
思路:在横向上寻找每一行都能满足的不完美循环节的最小的宽度作为最小覆盖子矩阵的宽,
在纵向上将每一行字符串当做一个字母,做一次kmp找不完美循环节的宽度作为最小覆盖子矩阵的高,
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
typedef pair<int,int>PII;
const int N=1e5+10,M=80;
int n,m;
char str[N][M];
int ne[N];
bool st[M];
int main()
{
cin>>n>>m;
memset(st,true,sizeof st);
for(int i=1;i<=n;i++)
{
scanf("%s",str[i]);
for(int j=1;j<=m;j++)
if(st[j])
{
for(int k=j;k<m;k+=j)//看相邻的包含j个数的两个区间是否相同。
{
for(int u=0;u<j&&k+u<m;u++)
if(str[i][u]!=str[i][k+u])
{
st[j]=false;
break;
}
if(!st[j]) break;
}
}
}
int width;
for(int i=1;i<=m;i++)
if(st[i])
{
width=i;
break;
}
// for(int i=1;i<=n;i++) str[i][width]=0;
for(int i=2,j=0;i<=n;i++)
{
while(j&&strcmp(str[i],str[j+1])) j=ne[j];
if(!strcmp(str[i],str[j+1])) j++;
ne[i]=j;
}
int height=n-ne[n];
cout<<width*height<<endl;
return 0;
}