Cyclic Nacklace 【HDU - 3746】【KMP补周期】

KMP算法的讲解,自己的领悟可随时提问

题目链接


题意:

有一个字符序列,现在问你:
序列后面最少补充几个元素使其恰能成为几个重复循环的序列。

题目还是很良心的,让我们求字符串后面放几个字符可以使其变成周期字符串,所以还是可以想到用KMP的next[]数组去计算的。


  我们先把周期计算出来,知道可以通过next[]来揣测最后应该放几个的,我们计算出最后一个字符的对应next[]值,然后用总长剪去它就是最小周期长度,然后既然已经知道最小周期长度,只需要比较当最小周期长度扩大到刚好大于原长时候的差值即是我们所要的答案了。

  还有一件事,如果恰好周期长度能被原长整除,且原长>1,就说明是恰好的完整的周期串。


#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN=1e5+5;
char s[maxN];
int len, nex[maxN];
void cal_next()
{
    nex[0] = nex[1] = 0;
    int k = 0;
    for(int i=2; i<=len; i++)
    {
        while(k>0 && s[k+1]!=s[i]) k = nex[k];
        if(s[k+1] == s[i]) k++;
        nex[i]=k;
    }
}
int main()
{
    int T;  scanf("%d", &T);
    while(T--)
    {
        getchar();
        scanf("%s", s+1);
        len=(int)strlen(s+1);
        cal_next();
        int tmp=len-nex[len];
        if(nex[len]==0) printf("%d\n", len);
        else if(len%tmp==0) printf("0\n");
        else
        {
            printf("%d\n", ((int)(len/tmp+1))*tmp-len);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41730082/article/details/83413919
今日推荐