题目链接
https://vjudge.net/problem/10934/origin
题目大意
一开始没看懂题目
给你一个字符串,让你输出有哪些前缀可以由某个串重复k次组成,输出最大k
解题思路
利用kmp的next数组
代码如下
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1e6+10;
char a[maxn];
int naxt[maxn];
int s;
void get_next()
{
int i=0,j=-1;
naxt[0]=-1;
while(i<s)
{
if(j==-1||a[j]==a[i])
{
i++;
j++;
if(i%(i-j)==0&&i/(i-j)>1)
printf("%d %d\n",i,i/(i-j));
if(a[i]!=a[j])
naxt[i]=j;
else
naxt[i]=naxt[j];
}
else
j=naxt[j];
}
}
int main()
{
int n,k=0;
while(cin>>n)
{
if(n==0)
break;
memset(a,0,sizeof(a));
k++;
scanf("%s",a);
s=strlen(a);
cout<<"Test case #"<<k<<endl;
get_next();
cout<<endl;
}
return 0;
}
这种我是套了一个模板。。。但是没看懂,下面这种比较好理解些
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1e6+10;
char a[maxn];
int naxt[maxn];
void get_next(int s)
{
int i=0,j=-1;
naxt[0]=-1;
while(i<s)
{
if(j==-1||a[j]==a[i])
{
i++;
j++;
naxt[i]=j;
}
else
j=naxt[j];
}
}
int main()
{
int n,k=0,i;
while(cin>>n)
{
if(n==0)
break;
memset(a,0,sizeof(a));
k++;
scanf("%s",a);
cout<<"Test case #"<<k<<endl;
get_next(n);
for(i=1;i<=n;i++)
{
if(i%(i-naxt[i])==0&&i!=i-naxt[i])//i-naxt[i]是循环节长度
cout<<i<<" "<<i/(i-naxt[i])<<endl;
}
cout<<endl;
}
return 0;
}