Hdu 1358 Period (KMP 求最小循环节)

题目链接:

  http://acm.hdu.edu.cn/showproblem.php?pid=1358

题目描述:

  给出一个字符串S,输出S的前缀能表达成Ak的所有情况,每种情况输出前缀的结束位置和k。

解题思路:

  打表算出next数组,然后对位置i求循环节,如果满足 i % (i - Next[i]) == 0 && Next[i] != 0,所对应的循环节(i - Next[i]), 循环次数是i / (i - Next[i])

 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 a[maxn];
13 int Next[maxn], m;
14 
15 void get_next (char a[])
16 {
17     int i, j;
18     Next[0] = j = -1;
19     i = 0;
20 
21     while (i < m)
22     {
23         while (j!=-1 && a[i]!=a[j])
24             j = Next[j];
25 
26         Next[++ i] = ++j;
27     }
28 }
29 
30 void solve  ()
31 {
32     for (int i=1; i<=m; i++)
33     {
34         if (Next[i] != 0 && i % (i - Next[i]) == 0)
35             printf ("%d %d\n", i, i / (i - Next[i]));
36     }
37     printf ("\n");
38 }
39 int main ()
40 {
41     int l = 0;
42     while (scanf ("%d",  &m), m)
43     {
44         scanf ("%s", a);
45         get_next (a);
46 
47         printf ("Test case #%d\n", ++l);
48 
49         solve ();
50     }
51     return 0;
52 }
53 /*
54 3
55 aabccb
56 */

 

posted @ 2016-04-21 20:40  罗茜  阅读(155)  评论(0编辑  收藏  举报