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。
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 }
原文:http://www.cnblogs.com/zyb993963526/p/6358096.html