题目大意:给你一些串,问如果想让这个串里面的循环节至少循环两次,需要添加几个字符(只能在最前面或者最后面添加)。比如ababc 需要添加5个就是添加ababc。
分析:其实字符串的长度len-next[len] = 最小循环节长度,为什么?其实也是需要对next的深刻了解,首先我们都知道next是求的最大的前缀和后缀的匹配度比如下面的字符串
ABCABCABC,很直接的就可以看出来最大的匹配串是ABCABC,但怎么从这个看出来最小的循环节呢?我们看到这个串的后缀串是从第4个字符开始的,也就是说从第四个字符开始到最后一直都是有匹配的,如下:
s[4] = s[1]
s[5] = s[2]
s[6] = s[3]
s[7] = s[4] !!!!
看到了什么s[7] = s[4] = s[1],其实这已经进入了循环,也就是后缀串前面的就是最小的循环节,如果还不明白可以自己在纸上比划比划。那么这道题懂了怎么求循环节想必大家也就会做了吧。
下面是AC代码
==========================================================================================================
#include<stdio.h> #include<string.h>const int MAXN = 1e5+7;char s[MAXN]; int next[MAXN];void GetNext(char s[], int next[], int N) {int i=0, j=-1;next[0] = -1;while(i<N){if(j==-1 || s[i]==s[j])next[++i] = ++j;elsej = next[j];} }int main() {int T;scanf("%d", &T);while(T--){scanf("%s", s);int N = strlen(s);GetNext(s, next, N);int cyclic = N-next[N], ans=0;if(cyclic == N)ans = N;else if(N % cyclic != 0)ans = cyclic-N%cyclic;printf("%d\n", ans);}return 0; }