POJ 1961 Period (弱鸡三战KMP)

题意:给你一个字符串S,求出字符串的每个前缀 是否存在一个字符串x,复制k次得到(k>1)

思路:这个的确花了我几分钟去思考,通过刚才的2个kmp板子题有了一些新的认识,我们重新读一遍题目会发现答案要求的其实还是一个串的最小循环节是几,但这次我们是对每一个前缀都求最小循环节,若k>1就记录答案

代码:

#include <cstdio>
#include <cstring >
#include <map>
using namespace std;

const int maxn=1e6+7;
char a[maxn];
int next[maxn];
int len;
map<int,int> mp;

void getnext()
{
    int j=0,k=-1;
    next[0]=-1;
    while(j<len){
        if(k==-1||a[j]==a[k])next[++j]=++k;
        else k=next[k];
    }
}
int main()
{
    int cas=1;
    while(~scanf("%d",&len)){
        if(!len)break;
        scanf("%s",a);
        mp.clear();
        getnext();
        for(int i=2;i<=len;i++){
            int as=i-next[i];
            if(i%as==0){
                int qw=i/as;
                if(qw>1){
                    mp[i]=qw;
                }
            }
//            printf("%d == %d
",i,next[i]);
        }
        map<int,int>::iterator it;
        printf("Test case #%d
",cas++);
        for(it=mp.begin();it!=mp.end();it++){
            printf("%d %d
",it->first,it->second);
        }
        puts("");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/lalalatianlalu/p/9641138.html