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

题意:题目研究了半天。就是说从字符串的第二个字符开始,看前面的字符串部分是否是循环的,如果是,则输出当前位置和循环的周期,循环的周期必须大于1。

        首先,需要好好理解next[]数组的含义,next数组的含义是:next[i]=k模式串下标为i的字符的前k个字符与开首的前k个字符相同。

        变量 t= i - next[i] 就是next数组下标和下标对应值的差,如果i%t==0,说明前面一定可以由一个前缀周期性的表示出来,循环的周期就是i/t。

HDU 1358 Period_next数组

 

 1 #include<iostream> 
 2 #include<cstring>
 3 #include<string>
 4 using namespace std;
 5 
 6 const int maxn = 1000000+5;
 7 
 8 int next[maxn], n;
 9 char pattern[maxn];
10 
11 void get_next()
12 {
13     int i, j;
14     i = -1;
15     j = 0;
16     ::next[0] = -1;
17     while (j<n)
18     {
19         if (i == -1 || pattern[i] == pattern[j])
20         {
21             ::next[++j] = ++i;
22         }
23         else
24             i = ::next[i];
25     }
26 }
27 
28 void solve()
29 {
30     for (int i = 2; pattern[i-1]; i++)
31     {
32         int t = i - ::next[i];
33         if (i%t == 0 && i/t>1)
34         {
35             cout << i  << " " << i/t << endl;
36         }
37     }
38 }
39 
40 int main()
41 {
42     //freopen("D:\\txt.txt", "r", stdin);
43     int kase = 0;
44     while (cin>>n && n)
45     {
46         scanf("%s", pattern);
47         //cout << pattern << endl << text << endl;
48         get_next();
49         cout << "Test case #" << ++kase << endl;
50         solve();
51         cout << endl;
52     }
53     return 0;
54 }