poj 1961 Period
一道KMP的题,题目大意是:给你一串字符s,求其前n位重复的次数大于一的所有子串。比如aaa,前两位是aa,所以重复的次数为2,前三位aaa重复的次数为3。
这题主要考察KMP算法中的next数组的灵活使用,next函数看过KMP的都知道,他是通过一个串的自匹配求出来的,next[i]一般认为是串s中前i个与后i个字符相等,并且这个i是满足条件的最大的。而通过求next的方法我们轻而易举的知道最大位移length=len(s)-next[len],所以要求前n位的最大重复字串,只要求出next数组就行了。
由于本人刚刚看懂KMP的next数组原理,所以本题做起来还是感到有点吃力,呵呵,继续研究KMP。。。。。
代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> int next[1000005]; char str[1000005]; void init() { int i,j; i=0;j=-1; next[0] = -1; while(str[i] != '\0') { if(j == -1 || str[i] == str[j]) { i++;j++; next[i]=j; } else j=next[j]; } } int main() { int cas,n,i; cas=1; while (scanf("%d",&n),n) { getchar(); scanf("%s",str); init(); printf("Test case #%d\n",cas++); for(i=2;i<=n;i++) { int x=i-next[i]; if(i%x == 0 && i/x > 1) printf("%d %d\n",i,i/x); } printf("\n"); } return 0; }