本题kmp的应用,现将宽度确定,题中范围是75,直接枚举宽度判断,也只能枚举判断
因为这题在行列上都可以不完全覆盖,当不完全覆盖时不满足所有循环节都是最小循环节的倍数,所以只能枚举
在找高度时使用kmp,在kmp比较是否相等时用strcmp,将每行宽度下一个赋值成0就是’/0’代表字符的结尾
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int N=10010,M=100;
int n,m,nxt[N];
char s[N][M];
bool st[M];
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
scanf("%s",s[i]);
for(int j=1;j<m;j++)
{
for(int k=j;k<m;k+=j)
{
for(int u=0;u<j&&u+k<m;u++)
if(s[i][u]!=s[i][u+k])st[j]=1;
}
}
}
int wet;
for(int i=1;i<=m;i++)if(st[i]==0){wet=i;break;}
for (int i = 1; i <= n; i ++ ) s[i][wet] = 0;
for(int i=2,j=0;i<=n;i++)
{
while(j && strcmp(s[i],s[j+1]) ) j=nxt[j];
if(!strcmp(s[i],s[j+1]))j++;
nxt[i]=j;
}
int het=n-nxt[n];
cout<<wet*het;
}
大佬,宽度可以不用枚举来判断吗?假设一个字符串,已求出next数组,n-next[n]显然是最小覆盖子串,但是次小的应该是n-next[next[n]]了吧,以此类推。我只是不严谨证明了一下。。(但是代码已经AC了)
y 总之前在他自己的代码下面的评论区回复过,说:
竖直方向为什么就可以使用n - next[n]了呢?它万一也不是完美循环节呢
可以参考基础课里讲的kmp,涉及到next数组的性质