题目链接:http://poj.org/problem?id=1961
通过next数组求字符串截止到i位置的最小循环节以及循环次数,可以在O(N)时间内得出,通过这个方法可以求得字符串的任意长度的循环节。
代码如下:
#include<iostream> #include<cstdio> using namespace std; #define maxn 1000010 char s[maxn]; int nxt[maxn]; int n; void pre(){ nxt[1]=0; for(int i=2,j=0;i<=n;i++){ while(j>0 && s[i]!=s[j+1])j=nxt[j]; if(s[i]==s[j+1])j++; nxt[i]=j; } } int main(){ int T=0; while(cin>>n && n){ scanf("%s",s+1); pre(); printf("Test case #%d ",++T); for(int i=2;i<=n;i++){ if(!(i%(i-nxt[i])) && nxt[i]){ printf("%d %d ",i,i/(i-nxt[i]));//到i位置为止的循环节 } } cout<<endl; } }