For each prefix of a given string S with N characters (each character has an ASCII code between 97 and 126, inclusive), we want to know whether the prefix is a periodic string. That is, for each i (2 <= i <= N) we want to know the
largest K > 1 (if there is one) such that the prefix of S with length i can be written as A K , that is A concatenated K times, for some string A. Of course, we also want to know the period K.
3 aaa 12 aabaabaabaab 0
Test case #1 2 2 3 3 Test case #2 2 2 6 2 9 3 12 4
【题解】
KMP算法应用题,题意是从序列首开始遍历,寻找相同子序列数大于等于2的序列终点位置和相同子序列的个数,比如样例1就是i=2时有两个相同的子序列a,a,序列i=3时有三个想通过的子序列a,a,a。
直接套用KMP模板,中间判断一下,如果符合条件就输出。
ps:这道题我实在virtual judge 上交的,ce了好几次,这个平台上不支持数组名与关键字相同,就是说,在代码中用next做数组名在电脑上可以运行,但是交上去会ce,所以稍微改一下数组名就好了。
【AC代码】
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e6+10;
int next_t[N];
string s;
int m,n;
void get_next()
{
int k=-1,i=0;
next_t[0]=-1;
while(i<s.size())
{
if(k==-1 || s[i] == s[k])
{
k++;
i++;
if(i%(i-k)==0 && i/(i-k)>1)
{
printf("%d %d\n",i,i/(i-k));
}
next_t[i]=k;
}
else
k=next_t[k];
}
}
int main()
{
int cnt=1;
while(~scanf("%d",&m),m)
{
cin>>s;
printf("Test case #%d\n",cnt++);
get_next();
cout<<endl;
}
return 0;
}