UVa1328 - Period(KMP找最短循环节)

题目大意

给定一个长度为n的字符串,求它的每个前缀的最短循环节

题解

白书例题~~~

”错位部分“长度为i-f[i],

{NSIZPH8WE}7_)8EV{~~MOG

如果这个前i个字符能够组成一个周期串,那么”错位”部分刚好是一个循环节i-f[i]就是循环节长度~~~~

代码:

#include <iostream>

#include <cstdio>

#include <cstring>

#include <algorithm>

using namespace std;

#define  MAXN 1000005

int f[MAXN];

char p[MAXN];

int main()

{

    int n,j,cases=1;

    while(scanf("%d",&n)!=EOF&&n)

    {

        printf("Test case #%d\n",cases++);

        scanf("%s",p);

        int len=strlen(p);

        f[0]=j=-1;

        for(int i=1;i<len;i++)

        {

            while(j>=0&&p[j+1]!=p[i]) j=f[j];

            if(p[j+1]==p[i]) j++;

            f[i]=j;

        }

        for(int i=1;i<len;i++)

            if(f[i]>=0&&((i+1)%(i-f[i])==0))

                printf("%d %d\n",i+1,(i+1)/(i-f[i]));

        printf("\n");

    }

    return 0;

}

你可能感兴趣的:(KMP)