码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 3746 (KMP求循环节)

时间:2015-07-15 16:40:15      阅读:118      评论:0      收藏:0      [点我收藏+]

标签:

题目链接: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 }
View Code

 

HDU 3746 (KMP求循环节)

标签:

原文地址:http://www.cnblogs.com/ikids/p/4648595.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!