HDU 3746 Cyclic Nacklace(KMP找循环节)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2087
题目大意:给你一个字符串,求出将字符串的最少出现两次循环节需要添加的字符数。
解题思路:
这题需要利用next数组的性质,求出字符串的最小循环节
有几个结论(具体可以看这里http://www.cnblogs.com/wuyiqi/archive/2012/01/06/2314078.html):
①字符串长度为len,则len-next[len]为最小循环节。
②如果len%(len-next[len])==0,此字符串的最小周期就为len/(len-next[len])。
借用以上结论,我们可以直接判断字符串是否已满足条件,或者需要补齐的字符数。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int N=1e6+5; 7 8 int len; 9 int nxt[N]; 10 char p[N]; 11 12 void getnext(){ 13 int i,j; 14 i=0,j=nxt[0]=-1; 15 while(i<len){ 16 while(j!=-1&&p[i]!=p[j]) 17 j=nxt[j]; 18 nxt[++i]=++j; 19 } 20 } 21 22 int main(){ 23 int t; 24 scanf("%d",&t); 25 while(t--){ 26 scanf("%s",p); 27 len=strlen(p); 28 getnext(); 29 int mmin=len-nxt[len]; //len-nxt[len]为字符串的最小循环节 30 if(len!=mmin&&len%mmin==0) //含有两个以上循环节 31 puts("0"); 32 else 33 printf("%d\n",mmin-len%mmin); //len%mmin等同于"abcab"减掉"abc" 34 } 35 return 0; 36 }