原题链接

考察KMP的运用

错误思路:

       我是求字符串中没有重合的最长前后缀,但这样的思路遇到cabc这样的测试数据显然是错误的,因为字符串复制时不一定会复制>=两遍

正解思路:

       按上面的思路,如果字符串复制两遍及以上,那么j的最大值就是答案,如果字符串复制少于2遍,答案应该是公共前后缀的长度+没有公共的部分

公共前后缀长度 = j

没有公共部分 = i-j+1-ne[i]-1 = i-j-ne[i]

因此答案为 i - ne[i]

2021.3.6 二刷已经不知道以前在写什么东西....简单来讲,设循环长度为x,ne[x+1] = 1,ne[x+2] = 2,ne[x+x+1] = x+1(第i周期回到第i-1周期)

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 const int N = 1e6+10;
 6 char s[N];
 7 int len,ne[N];
 8 int main()
 9 {
10 //    freopen("in.txt","r",stdin);
11     scanf("%d%s",&len,s+1);
12     for(int i=2,j = 0;i<=len;i++){
13         while(j&&s[i]!=s[j+1]) j = ne[j];
14         if(s[i]==s[j+1]) j++;
15         ne[i] = j;
16     }
17     printf("%d\n",len-ne[len]);
18     return 0;
19 }