题意:
给你一串字符串,问你是否存在循环节,如果存在输出循环节的次数。
还是说一下样例吧:
第一组:
2 2 表示的是第一个字母到第二字母,a出现了两次。
3 3 表示的是第一个字母到第三个字母,a出现了3次。
第二组:
2 2表示的是第一个字母到第二个字母,a出现了两次。
6 2表示的是第一个字母到第六个字母,aab出现了两次。
9 3表示的是第一个字母到第九个字母,aab出现了三次。
12 4表示的是第一个字母到第十二个字母,aab出现了四次。
不要问什么没有1 1因为KMP的前缀后缀中单个字符不算的。
题解:
求KMP循环次数,我们枚举每个位置查看是否存在循环节存在就输出当前位置和循环次数,注意的就是next数组是向后挪一位的,所以我们在枚举的时候i+1,下面的还是看代码吧。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int MAXN=1000000+7;
char s[MAXN];
int Next[MAXN];
void getNext()
{
Next[0]=-1;
int j=0,k=-1;
int slen=strlen(s);
while(j<slen)
{
if(k==-1||s[j]==s[k])
{
j++;
k++;
Next[j]=k;
}
else
k=Next[k];
}
}
int main()
{
int n,k=1;
while(~scanf("%d",&n),n)
{
scanf("%s",s);
getNext();
// for(int i=0;i<=n;i++)
// printf("%d ",Next[i]);
// printf("~~~~~~~~~~~~~~\n");
printf("Test case #%d\n",k++);
for(int i=1;i<n;i++)
{
int L=(i+1)-Next[i+1];
if((i+1)%L==0&&(i+1)!=L)
printf("%d %d\n",i+1,(i+1)/L);
}
printf("\n");
}
}