感觉题意很难懂啊啊。。。
给定一个序列,判断这个序列所有前缀是否存在大于1的最小循环节
若存在则输出这个前缀的长度以及对应的最小循环节循环次数
我开始的做法是枚举所有的前缀,用get_next()求出next数组值
再用len % (len-next[len]) == 0判断
毫无疑问的超时了。。。
看了别人的才知道自己傻逼了
既然可以用len%(len-next[len]) == 0判断
为什么不能用 i%(i-next[i]) == 0 判断呢
代码如下:
#include <cstdio>
#include <cstring>
#define MAXN 1000100
using namespace std;
int n;
int next[MAXN];
char str[MAXN];
char tmp[MAXN];
void get_next(char p[]) {
int i = 0, j = -1;
next[0] = -1;
while(i < n) {
if(j==-1 || p[i]==p[j]) {
++i, ++j;
next[i] = j;
} else j = next[j];
}
}
int main(void) {
int cnt = 1, j;
while(scanf("%d", &n), n) {
scanf("%s", str);
get_next(str);
printf("Test case #%d\n", cnt++);
for(int i=0; i<n; ++i) {
j = i+1;
if(j%(j-next[j])==0 && j/(j-next[j])>1)
printf("%d %d\n", j, j/(j-next[j]));
}
puts("");
}
return 0;
}