版权声明: https://blog.csdn.net/weixin_39778570/article/details/81987726
题意:给定一个字符串,他自身重复n次后,在这个新串中切出中间一串,求一个最短的循环节长度
分析:这个题允许我们循环节不完整,也就是说abcd循环3次且出来的串cdabcd这里的最短循环节为abcd,而多出来的cd是合法子串
所以实际上,我们只要找到最短的前后缀,剩下的长度就是最短循环节的长度,如abcda,前后缀为a,身下bcda,bcdefbcd前后缀为bcd剩下efbcd,bcdeabcdeabc,前后缀为bcdeabc剩下deabc
这里再说明一下,一个重复串中有这样三个子串ABA,那么BA一定为一个完整的串
AC code
#define _CRT_SBCURE_NO_DEPRECATE
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define maxn 1000005
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
int nxt[maxn];
char p[maxn];
int m,ans;
int main(){
while(scanf("%s", p+1) != EOF){
m = strlen(p+1);
nxt[0] = -1;
int j = -1;
for(int i=1; i<=m; i++){
while(j>=0 && p[j+1]!=p[i]) j = nxt[j];
nxt[i] = ++j;
}
ans = m - nxt[m];
printf("%d\n", ans);
}
return 0;
}