Period(kmp中next数组的运用)

【题目来源】:https://vjudge.net/problem/HDU-1358
【题意】
给出一个长度为n的字符串,问,在字符1~n个里,前缀是周期串的是哪个?输出i,并且输出这i个字符里最小周期的个数k,并且,k不能是1。
举个例子说明一下:
abcabcabcabc
那么输出:
6 2
9 3
12 4。
先是字符串:abcabc,是周期串,最小周期是3,k是2(也就是有两个最小周期),以此类推,。
【思路】
依旧利用kmp中的next数组,这一题类似于Cyclic Nacklace,只不过那一道是给你固定的长度,而这个是给了一个范围,直接for循环暴力。
最重要的是要明白next数组存的内容代表什么,最好自己模拟一遍写出next数组。会发现,当前的长度减去当前的next值就是当前前缀的最下周期。
【代码】

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int mod=1e9+7;
const double esp=1e-5;
typedef unsigned long long ll;
typedef long long LL;
char s[1000000+10];
int nexts[1000000+10];
int len;
void get_next()
{
    int i=0,j;
    j=nexts[0]=-1;
    while(iwhile(-1!=j&&s[i]!=s[j]) j=nexts[j];
        nexts[++i]=++j;
    }
}
int main()
{
    int cases=1;
    while(~scanf("%d%*c",&len)&&len)
    {
        scanf("%s",s);
        get_next();
//        for(int i=0;i<=len;i++)
//        {
//            printf("%d ",nexts[i]);
//        }
//        printf("\n");
        printf("Test case #%d\n",cases++);
        for(int i=0;iint x=i+1;
            int y=x-nexts[x];
            if(x%y==0&&x/y!=1)
            {
                printf("%d %d\n",x,x/y);
            }
        }
        printf("\n");
    }
}

你可能感兴趣的:(ACM竞赛,【字符串】--KMP,ACM的进程)