hdu-3746(kmp)

题意:给你一个字符串,问你至少增添几个字符可以把这个字符串变成一个循环字符串(ababa的循环节是ab,不是aba);

解题思路:利用kmp中的next数组,首先在这样求next的数组的代码里:

void get_next()
{
    int j,k;
    j=0;k=-1;next1[0]=-1;
    while(j<tlen)
    {
        if(k==-1||t[j]==t[k])
            next1[++j]=++k;
        else
            k=next1[k];
    }
}

 

next1[tlen]=我们输入的完整字符串的相同前后缀,然后tlen-next1[tlen]=循环节的长度;因为,一个字符串,例如:abcdabcd本身就是循环字符串或者abcdxyzabc这样的,所以当我们求出了tlen-next[tlen]

的时候只有三个情况,这个字符串是循环的,这个不是循环的但是字符串末尾有一部分循环节,这个不是循环的,且本身是一个也只有这个一个循环节,所以通过计算前后缀可以得到后面的重复部分,前后缀为0,没有循环节重复,不为零,有重复部分;

完整代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<math.h>
#include<cstdlib>
using namespace std;
char t[100500];
int next1[100500];
int tlen;
void get_next()
{
    int j,k;
    j=0;k=-1;next1[0]=-1;
    while(j<tlen)
    {
        if(k==-1||t[j]==t[k])
            next1[++j]=++k;
        else
            k=next1[k];
    }
}
int main()
{
    int tt;
    scanf("%d",&tt);
    while(tt--)
    {
        gets(t);
        tlen=strlen(t);
        get_next();
        int minn=tlen-next1[tlen];
        if(tlen!=minn&&(tlen%minn==0))
        {
            printf("0\n");
        }
        else
            printf("%d\n",minn-(tlen%minn));
    }
}

  

posted @ 2018-07-09 15:34  荒岛的龟  阅读(472)  评论(0编辑  收藏  举报