POJ 2406 Power Strings
原题链接:http://poj.org/problem?id=2406
首先给出一个结论:对于给定长度为n的字符串,如果n % (n - next[n]) == 0,那么,n - next[n] 为字符串的最小周期(最小循环节)。
这里给出我自己的证明:
设字符串为s,长度为n,为便于叙述下标从1开始。
现在有next[n] = j,从next数组的定义出发我们知道s[n-j-j+1...n-j] = s[n-j+1...n],如下图:
显然灰色“区域2”为s[n-j-j+1...n-j],而由kmp匹配的过程可知,灰色的两个区域——区域2’和区域2是相等的,好了,继续重复这个步骤把 区域2’ 放到上面,就可以不断地以n - next[n]大小的块儿不断向前推进,如果n % (n - next[n]) == 0,那么 n / (n-next[n])就是最高周期次数了。
#include <stdio.h> #include <string.h> const int maxn = 1000000 + 5; char s[maxn]; int next[maxn]; int n, cnt; void get_next() { int i = 0, j = -1; next[0] = -1; while(i < n) { if(j == -1 || s[j] == s[i]) { i++; j++; next[i] = j; } else j = next[j]; } } int solve() { int t = n - next[n]; return n % t == 0 ? n / t : 1; } int main() { while(scanf("%s", s) != EOF && s[0] != '.') { n = strlen(s); get_next(); printf("%d\n", solve()); } return 0; }