HDU-4763 Theme Section

来源:互联网 发布:什么是淘宝钻石买家 编辑:程序博客网 时间:2024/05/17 08:55

题目:

http://acm.hdu.edu.cn/showproblem.php?pid=4763

题意:

一首歌有一个主题部分,就是在开头,结尾和中间都出现的一段歌词,现在给出k首歌的歌词,找出每首歌的主题部分长度。

思路:

就是求最长子段是前缀,后缀和中间出现,并且不重叠。

既是前缀又是后缀,那就明显是kmp的next数组可以直接求得,next[len]的值就是了。

再就是要找该部分在中间出现过,直接扫一遍中间是否出现过next[len],

保证互相覆盖就是只扫2*next[len]到len-next[len]的部分。

另外可能出现结果不是最长前后缀的情况,就是搜索失败的时候找next[next[len]],也就是最长前后缀中也是前后缀的长度。

枚举找下去就是了。主要是熟悉kmp。

代码:

#define N 1123456int n,m;int flag,sum,ave,ans,res,len,ans1,ans2;int a[N];char s[N];void getnext(char *pre, int len, int *next){    int i = 0,j = -1;    next[0] = -1;    while(i < len)    {        if(j == -1 || pre[i] == pre[j])        {            i++;            j++;            next[i] = j;        }        else            j = next[j];    }}int main(){    int i,j,k,kk,t,x,y,z;    scanf("%d",&k);    while(k--)    {        scanf("%s",s);        m = n = strlen(s);        getnext(s,n,a);        flag = 1;        while(n>0 && flag)        {            res=a[n];            for(i=2*res;flag && i<=m-res;i++)                if(a[i]==res)                    flag = 0;            n=a[n];        }        printf("%d\n",res);    }    return 0;}











0 0
原创粉丝点击