HDU-1358 Period 发表于 2019-10-26 | 阅读次数: 题目链接题意概括:找出从第二个字符开始,之前所有的字符是否是循环串,如果是,输出当前字符的下标(此题下标从1开始)和周期(T>1)Just read code. code1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950//本题利用KMP算法中求Next[]数组的性质可以解决;//即如果一个字符串为循环串时,(例如adcabcabc)那么它的next[]数组满足下面性质://1、len%(len-pre[len])==0;2、len/(len-pre[len])就是循环的次数;这里len是字符串的长度,pre[]是next[]数组;#include <bits/stdc++.h>using namespace std;#define endl '\n'const int maxn = 1e6 + 9;int pre[maxn], n;char s[maxn];void pre_fun(){ for (int i = 1; i <= n; ++i) { int j = pre[i - 1]; while (j > 0 && s[i] != s[j]) j = pre[j - 1]; if (s[i] == s[j]) j++; pre[i] = j; }} //注意不同的next数组习惯,使用前应该输出next数组查看int main(){ // ios::sync_with_stdio(0); // cin.tie(0); int ca = 0; while (cin >> n, n) { cin >> s; pre_fun(); // for (int i =0 ; i < n; ++i) // cout << pre[i] << ' '; // cout<<endl; cout << "Test case #" << ++ca << endl; for (int i = 0; i < n; ++i) { // cout << pre[i] << ' '; if (pre[i] < 1) continue; int j = i + 1 - pre[i]; //显然,下标为0,字符串长度为1 // cout<<j<<' '; if (j > 0 && (i + 1) % j == 0) { cout << i + 1 << ' ' << (i + 1) / j << endl; } } cout << endl; } return 0;}