Uva(1328)(Period)

链接:https://vjudge.net/problem/UVA-1328
思路:原来感觉都是暴力做的,但因为数据水所以能过,现在刚学了kmp发现可以用kmp做这种查找循环节的问题,具体就是求出f数组(next数组),然后当i%(i-f[i])==0(表示从开头到当前位置)的长度是这个相同最长前缀的长度的整数倍的话,则错位部分的第一段等于原来的第二段,第二段等于第三段-------,一直可以推出等分的每一段都相等,这样就可以推出是一个循环节,如果不能整除肯定不为循环节- -,证明完毕~~
代码:

#include
using namespace std;
int n;
const int maxn = 1e6+10;
char a[maxn];
int f[maxn];

int main(){
    int kase = 0;
    while(~scanf("%d",&n)&&n){
        scanf("%s",a);
        f[0] = f[1] = 0;
        for(int i=1;i0&&i%(i-f[i])==0)
            printf("%d %d\n",i,i/(i-f[i]));
        }
        printf("\n");
    }
    return 0;
}

你可能感兴趣的:(Uva(1328)(Period))