标签:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3746
题意:给一段字符串,求添加多少个字符,使得这个字符串至少循环两次。
题解:先求的next数组,然后,len-next[len]的值为最小循环节。所以,如果len能够整出这个循环节,则已经构成了循环了,如果next[len]=0,则说明没有循环节,则输出len,其余情况,则输出构成最后一个循环节所需字符串,其值为len-next[len]-len%(len-next[len])即最小循环节减去长度对最小循环节取余。
疑问一:为什么len-next[len] 为最小循环节?
http://www.cnblogs.com/wuyiqi/archive/2012/01/06/2314078.html
疑问二:为什么len-next[len]-len%(len-next[len])为所求需要添加的字符串?
这是因为长度对最小循环节取余之后,最后一个循环节已经有这么多字符了,而循环节一共需要len-next[len]所以,减去得到的值就应该是补充的了!
代码如下:
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<string> 6 using namespace std; 7 const int maxn=100005; 8 int Next[maxn]; 9 char s[maxn]; 10 void getNext(int len) 11 { 12 int i=0,j=-1; 13 Next[0]=-1; 14 while(i<len) 15 { 16 if(j==-1||s[i]==s[j]) 17 { 18 i++; 19 j++; 20 Next[i]=j; 21 } 22 else 23 j=Next[j]; 24 } 25 } 26 int main() 27 { 28 int t; 29 cin>>t; 30 while(t--) 31 { 32 scanf("%s",s); 33 int l=strlen(s); 34 getNext(l); 35 int t=l-Next[l]; 36 // for(int i=0;i<=l;i++) 37 // cout<<Next[i]<<" "; 38 if(Next[l]==0) 39 printf("%d\n",l); 40 else if(!(l%t)) 41 printf("0\n"); 42 else 43 printf("%d\n",t-l%t); 44 } 45 }
标签:
原文地址:http://www.cnblogs.com/ikids/p/4648595.html