Cyclic Nacklace

题目大意:给你一些串,问如果想让这个串里面的循环节至少循环两次,需要添加几个字符(只能在最前面或者最后面添加)。比如ababc 需要添加5个就是添加ababc。

分析:其实字符串的长度len-next[len] = 最小循环节长度,为什么?其实也是需要对next的深刻了解,首先我们都知道next是求的最大的前缀和后缀的匹配度比如下面的字符串

ABCABCABC,很直接的就可以看出来最大的匹配串是ABCABC,但怎么从这个看出来最小的循环节呢?我们看到这个串的后缀串是从第4个字符开始的,也就是说从第四个字符开始到最后一直都是有匹配的,如下:
s[4] = s[1]
s[5] = s[2]
s[6] = s[3]
s[7] = s[4] !!!!
看到了什么s[7] = s[4] = s[1],其实这已经进入了循环,也就是后缀串前面的就是最小的循环节,如果还不明白可以自己在纸上比划比划。那么这道题懂了怎么求循环节想必大家也就会做了吧。
下面是AC代码
==========================================================================================================
#include<stdio.h>
#include<string.h>

const int MAXN = 1e5+7;

char s[MAXN];
int next[MAXN];

void GetNext(char s[], int next[], int N)
{
    int i=0, j=-1;
    next[0] = -1;
    while(i<N)
    {
        if(j==-1 || s[i]==s[j])
            next[++i] = ++j;
        else
            j = next[j];
    }
}

int main()
{
    int T;

    scanf("%d", &T);

    while(T--)
    {
        scanf("%s", s);

        int N = strlen(s);

        GetNext(s, next, N);

        int cyclic = N-next[N], ans=0;

        if(cyclic == N)
            ans = N;
        else if(N % cyclic != 0)
            ans = cyclic-N%cyclic;

        printf("%d
", ans);
    }

    return 0;
}
原文地址:https://www.cnblogs.com/liuxin13/p/4730441.html