【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 }
View Code

 

posted @ 2017-07-04 22:01  shulin15  阅读(196)  评论(0编辑  收藏  举报