http://poj.org/problem?id=1961
分析:
S的长度为i的前缀可以表示成A^K形式,求i和K。KMP中next数组的应用。
Out:
2 2
6 2
9 3
12 4
依次继续,由于整除最后蓝色小块与红色小块会重合,H=T,所以
K=i/(i-next[i]);
2.2 i%(i-next[i])!=0
则由2.1可知随着步骤继续,由于不整除,H和T在在相遇处会有重叠部分也即H!=T.
程序中i!=len是排除K=1的情况,也即next[i]=0的情况。
(个人理解,如果有错还望大家指正~)
代码:
<span style="font-size:14px;">//Period
#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
using namespace std;
#define MAXN 1000003
int plen;
int next[MAXN];
char pat[MAXN];
void getNext()
{
int j=0,k=-1;
next[0]=-1;
while(j<plen){
while(k>-1 && pat[j]!=pat[k]) k=next[k];
next[++j]=++k;
}
}
int main()
{
freopen("in.txt","r",stdin);
int n;
int cno=1;
while(scanf("%d",&n),n){
printf("Test case #%d\n",cno++);
scanf("%s",pat);
plen=strlen(pat);
getNext();
for(int i=1;i<=plen;i++){
int len=i-next[i]; //循环节长度
if(i!=len && i%len==0) //不止一个循环节,因为k>1
printf("%d %d\n",i,i/len);
}
printf("\n");
}
return 0;
}</span>