P4391 [BOI2009]Radio Transmission 无线传输
考察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 }