题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1358
题目大意:给你一个长度为 (n) 的字符串 (s) ,那么它有 (n) 个前缀。
对于第 (i) 个前缀 (t) ,如果他们表示成一个子串重复 (K) 次 ((K>1)) ,那么我们就输出这个前缀 (t) 的长度以及对应的最大的 (K) 。(因为对于 (aaaa) 来说,(K) 可以为 (4) 或者 (2) ,但是 (4) 比较大,所以选择 (K) )。
题目分析:考察 (next) 函数的应用。我们假设长度为 (i) 的前缀, (i-nxt[i]) 能够整除 (i) ,那么 (K=i/(i-nxt[i])) 。
实现代码如下:
#include <cstdio>
#include <string>
using namespace std;
const int maxn = 1001000;
int m, nxt[maxn], cas = 1;
string t;
char ch[maxn];
string read() {
scanf("%s", ch);
string tmp_s = ch;
return tmp_s;
}
void cal_next() {
m = t.length();
for (int i = 0, j = -1; i < m; i ++) {
while (j != -1 && t[j+1] != t[i]) j = nxt[j];
nxt[i] = (j+1 < i && t[j+1] == t[i]) ? ++j : -1;
}
}
int main() {
while ( ~scanf("%d", &m) && m ) {
t = read();
cal_next();
printf("Test case #%d
", cas ++);
for (int i = 0; i < m; i ++) {
int len = i + 1;
int delta = i - nxt[i];
if (len % delta == 0 && len / delta > 1) {
printf("%d %d
", i+1, len/delta);
}
}
puts("");
}
return 0;
}
作者:zifeiy