关于KMP的最短循环节、循环周期,请戳:
http://www.cnblogs.com/chenxiwenruo/p/3546457.html (KMP模板,最小循环节)
POJ 2406 Power Strings
题意:
给一个字符串,问这个字符串是否能由另一个字符串重复R次得到,求R的最大值。
#include <iostream> #include <stdio.h> #include <string.h> /* 题意: 给一个字符串,问这个字符串是否能由另一个字符串重复R次得到,求R的最大值。 */ using namespace std; const int maxn=1000005; int next[maxn]; char str[maxn]; void getnext(char *str,int len){ next[0]=-1; int i=0,j=-1; while(i<len){ if(j==-1||str[i]==str[j]){ i++; j++; next[i]=j; } else j=next[j]; } } int main() { while(scanf("%s",str)!=EOF){ if(str[0]=='.') break; int len=strlen(str); getnext(str,len); int l=len-next[len]; if(len%l==0) printf("%d ",len/l); else printf("1 "); } return 0; }
POJ 1961 Period
给你一个字符串,对于它长度为i的前缀(i=2~n),给出对应的循环周期k,即前缀可由某个字符串拼接k次得到(k>1)
2406的加强版
#include <iostream> #include <stdio.h> #include <string.h> /* 给你一个字符串,对于它长度为i的前缀(i=2~n),给出对应的循环周期k,即前缀可由某个字符串拼接k次得到(k>1) 2406的加强版 */ using namespace std; const int maxn=1000005; int next[maxn]; char str[maxn]; int n; void getnext(char*str,int len){ next[0]=-1; int i=0,j=-1; while(i<len){ if(j==-1||str[i]==str[j]){ i++;j++; next[i]=j; } else j=next[j]; } } int main() { int cases=0; while(scanf("%d",&n),n){ scanf("%s",str); getnext(str,n); printf("Test case #%d ",++cases); for(int i=2;i<=n;i++){ int l=i-next[i]; if(i%l==0 && i/l>1){ printf("%d %d ",i,i/l); } } printf(" "); } return 0; }