链接
思路
把环展开,变成长度为两倍的链,暴力 KMP 匹配每两个串。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
char ch[110][20010];
int f[110][10010], g[20010], ok[110];
int n, m, cnt;
void get_f(){
for(int i = 1; i <= n; i ++){
int p = 0;
for(int j = 2; j <= m; j ++){
while(p && ch[i][j] != ch[i][p+1]) p = f[i][p];
if(ch[i][j] == ch[i][p+1]) p ++;
f[i][j] = p;
}
}
}
bool kmp(int x, int y){
int p = 0;
for(int i = 1; i <= 2*m; i ++){
while(p && ch[x][i] != ch[y][p+1]) p = f[y][p];
if(ch[x][i] == ch[y][p+1]) p ++;
if(p == m) return true;
}
return false;
}
void add_ok(int x){
for(int i = 1; i <= m; i ++) ch[x][i+m] = ch[x][i];
ok[++cnt] = x;
}
int main(){
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i ++) scanf("%s", ch[i]+1);
get_f();add_ok(1);
for(int i = 2, is = 1; i <= n; i ++, is = 1){
for(int j = 1; j <= cnt; j ++)
if(kmp(ok[j],i) == 1){is = 0;break;}
if(is) add_ok(i);
}
printf("%d", cnt);
return 0;
}