POJ
来源:互联网 发布:淘宝上怎么买身份证 编辑:程序博客网 时间:2024/06/07 05:53
传送门:点击打开链接
题意就是寻找一个字符串前缀的最短循环节,从而求出最大循环数。利用KMP算法可以求出Next数组,然后根据Next数组的定义,我们可以知道对于一个前缀S
1.如果i % (i - Next[i]) == 0,则S是有循环节的,循环节长度为i - Next[i]。
2.因为Next[i]表示最长前后缀,所以i - Next[i]是最短循环节。
3.Next[i]不能为0,否则就表示S循环节是其自身。
代码如下:
#include <cstring>#include <cstdlib>#include <cstdio>using namespace std;const int N = 1000005;char T[N];int lent;int Next[N];void getNext(){ int i = 0; int k = -1; Next[0] = -1; while (i < lent) if (k == -1 || T[i] == T[k]) Next[++i] = ++k; else k = Next[k];}int main(){ //freopen("test.txt", "r", stdin); //freopen("out.txt", "w", stdout); int Case = 1; while (~scanf("%d", &lent) && lent) { scanf("%s", T); lent = strlen(T); getNext(); printf("Test case #%d\n", Case++); for(int i = 1; i <= lent; i++) { /* 如果i % (i - Next[i]) == 0满足,则i - Next[i]为循环节长度。 但是循环节长度又不能是总长度,所以Next[i] != 0。 */ if (i % (i - Next[i]) == 0 && Next[i]) printf("%d %d\n", i, i / (i - Next[i])); } printf("\n"); } return 0;}
阅读全文
0 0