您的位置:首页 > 其它

Period hdu1358 KMP

2013-02-20 19:19 204 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1358

过了个年。疯玩了很久。一直都没写题。深感惭愧 …

解析参考前辈的博客 http://fudq.blog.163.com/blog/static/19135023820126523434614/

题意 利用第二组测试数据来解释:

input:

12

aabaabaabaab

output:

Test case #2

2 2

6 2

9 3

12 4

第二行的2 2,意思是,从第1个字母到第2字母组成的字符串可由某一周期性的字串(“a”)的两次组成,也就是aa有两个a组成;

第三行自然就是aabaab可有两个aab组成;

第四行aabaabaab可由三个aab组成;

第五行aabaabaabaab可有四个aab组成

思路:

这个题主要考察kmp算法中next数组的应用,大致思路是这样的:求出next数组后(next[0]~next[len]),从i=2(也就是第三个 字符)开始,令j=i-next[i],j可以整除i,则说明存在,输出i和i/j;为什么要这样做呢,j=i-next[i]就是看i和next[i] 之间有多少个字母,然后如果i%j==0,则说明i之前一定有一个周期性的字串,长度为i-j,次数为i/j.

#include <iostream>
using namespace std;
#define NLEN 1000005
char s[NLEN];
int nextd[NLEN];

void getnext(int len){
nextd[0]=-1;
nextd[1]=0;
int j=1,k=0;
while (j<len){
if (s[j]==s[k]){
nextd[j+1]=k+1;
j++;
k++;
}
else if (k==0){
nextd[j+1]=0;
j++;
}
else k=nextd[k];
}
}

int main(){
#ifndef ONLINE_JUDGE
freopen("1358in.txt","r",stdin);
#endif
int len,ce=0,i,j;
while (scanf("%d",&len)!=EOF&&len){
ce++;
scanf("%s",s);
getnext(len);
printf("Test case #%d\n",ce);
for (i=2;i<=len;i++){
j=i-nextd[i];
if (nextd[i]&&i%j==0)
printf("%d %d\n",i,i/j);
}
putchar(10);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: