题目:
链接:http://acm.hdu.edu.cn/showproblem.php?pid=1358
题意:
给出字符串的长度n,输入字符串s,直到输入n=0结束。求出s的所有周期性前缀的长度和相应的周期。
算法:
KMP算法。求出s串的next数组,然后用依次判断每个前缀是否具有周期性。(在if(next[i+1]%num == 0 && next[i+1]!=0)处,直接输出耗时110毫秒,保存在数组中是93毫秒)。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n;
char s[1000010],s1[1000010];
int next[1000010],a[1000010][2];
void get_nextval(char s[],int len)
{
int i,j;
i = -1;
j = 0;
next[0] = -1;
while(j<len)
{
if(i == -1 || s[i] == s[j])
{
++j; ++i;
next[j] = i;
}
else
i = next[i];
}
}
int main()
{
//freopen("input.txt","r",stdin);
int num;
int kase = 0;
int ct;
while(scanf("%d",&n) != EOF && n)
{
memset(a,0,sizeof(a));
getchar();
gets(s);
ct = 0;
get_nextval(s,n);
printf("Test case #%d\n",++kase);
for(int i=1; i<n; i++)
{
num = (i+1)-next[i+1];//重复串的长度
if(next[i+1]%num == 0 && next[i+1]!=0)
{
a[ct++][0] = i+1;
a[ct-1][1] = (i+1)/num;
}
}
for(int i=0; i<ct; i++)
printf("%d %d\n",a[i][0],a[i][1]);
cout<<endl;
}
return 0;
}