【KMP+最小循环节】F. Cyclic Nacklace
https://www.bnuoj.com/v3/contest_show.php?cid=9147#problem/F
【题意】
给定一个字符串,问在字符串后最少添加多少个字母,得到的新字符串能是前缀循环的字符串。
【思路】
这道题的关键是要理解KMP中的nxt数组什么含义。
nxt[i]就是以i结尾的字符串中前缀和后缀匹配的最长长度。
所以len-nxt[len]就是最小循环节。
如abcdab,nxt[len]就是2,最小循环节就是4(abcd)。
理解了这个这道题就迎刃而解了。
【网上解释】
http://www.cnblogs.com/wuyiqi/archive/2012/01/06/2314078.html
【Accepted】
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<string> 6 #include<cstring> 7 using namespace std; 8 int n; 9 const int maxn=1e5+10; 10 const int inf=0x3f3f3f3f; 11 char str[maxn]; 12 int nxt[maxn]; 13 typedef long long ll; 14 void kmp_pre(int m) 15 { 16 int i,j; 17 j=nxt[0]=-1; 18 i=0; 19 while(i<m) 20 { 21 while(i<m) 22 { 23 while(j!=-1&&str[i]!=str[j]) 24 { 25 j=nxt[j]; 26 } 27 nxt[++i]=++j; 28 } 29 } 30 } 31 int main() 32 { 33 int T; 34 scanf("%d",&T); 35 while(T--) 36 { 37 memset(nxt,0,sizeof(nxt)); 38 scanf("%s",str); 39 int len=strlen(str); 40 kmp_pre(len); 41 //cout<<nxt[len]<<endl; 42 int ans=len-nxt[len]; 43 if(ans!=len&&len%ans==0) 44 { 45 printf("0\n"); 46 } 47 else 48 { 49 printf("%d\n",ans-(len-(len/ans)*ans)); 50 } 51 } 52 return 0; 53 }