FZU1901(Next数组的应用)

题目链接:http://acm.fzu.edu.cn/problem.php?pid=1901
题意:求某个前缀,可以使得前缀和剩下部分能够一一对应,可以是原串。

题解:Next数组的应用,首先 t=Next[len] 的意义是(假设1-t意思是前面t个字符):s[1....t]=s[len-t,len](后面t个字符) 那么,此时len-t的含义就是,把相同部分(前面t个)+不相同部分(去掉前t个和后t个部分)作为前缀则满足题意,所以,只要不断向下找Next的值,则可以求的每一个前缀,直到Next的值为0.

小知识点:k = len-Next[len] 且 len % k == 0 且 Next[len]!=0 则k为len长度下的最小循环节

 

代码如下:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 const int maxn=1000000+50;
 7 char s[maxn];
 8 int Next[maxn];
 9 int sum[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             i++,j++,Next[i] = j;
18         else
19             j = Next[j];
20     }
21 }
22 int main()
23 {
24     int test;
25     cin>>test;
26     int temp=1;
27     while(test--)
28     {    
29         scanf("%s",s);
30         int len=strlen(s);
31         getNext(len);
32         int j=Next[len];
33         int sum1=0;
34         while(j)
35         {
36             sum[sum1++]=len-j;
37             j=Next[j];
38         }
39         sum[sum1++]=len;
40         printf("Case #%d: %d\n",temp++,sum1);
41         for(int i=0;i<sum1-1;i++)
42             printf("%d ",sum[i]);
43         printf("%d\n",sum[sum1-1]);
44     }
45 }
View Code

 

posted on 2015-07-19 17:09  小松song  阅读(128)  评论(0)    收藏  举报

导航