Fzu Problem 1901 Period II (kmp)

题目链接:

  Problem 1901 Period II

题目描述:

  给出一个串,满足长度为p的前缀和长度为p的后缀相等的p的个数,输出p的个数,和p分别是多少?

解题思路:

  对kmp的next数组的理解程度,next[i] = j的时候,就是当子串匹配到i的时候失配,就回溯到j的位置从新匹配,(s[0, j] == s[i-j, i])

  对于next[len] = x, s[0, x] == s[len-x, len].

  next[x] = y, s[0, y] == s[x - y, x];

  因为s[0, x] == s[len - x, len],      s[0, y] == s[x - y, x], 可以得出来 s[len - x - y, len] == s[x - y, x].

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 
 8 #define LL long long
 9 #define maxn 1000010
10 #define mod 100000007
11 
12 char b[maxn];
13 int Next[maxn], n, m, l;
14 int ans[maxn];
15 
16 void Get_Next ()
17 {
18     int i, j;
19     j = Next[0] = -1;
20     i = 0;
21 
22     while (i < m)
23     {
24         while (j!=-1 && b[i]!=b[j])
25             j = Next[j];
26 
27         Next[++ i] = ++ j;
28     }
29 }
30 
31 void kmp ()
32 {
33     Get_Next ();
34     int x = 0;
35     for (int i=m; i>0; i=Next[i])
36         ans[x ++] = m - Next[i];
37 
38     printf ("Case #%d: %d\n", ++l, x);
39     for (int i=0; i<x; i++)
40         printf ("%d%c", ans[i], i==x-1?'\n':' ');
41 }
42 
43 int main ()
44 {
45     int T;
46     l = 0;
47     scanf ("%d", &T);
48 
49     while (T --)
50     {
51         scanf ("%s", b);
52         m = strlen (b);
53         kmp ();
54     }
55     return 0;
56 }

 

posted @ 2016-04-28 16:15  罗茜  阅读(193)  评论(0编辑  收藏  举报