HDU 4763 Theme Section(KMP:后缀与前缀)

558 篇文章 0 订阅
273 篇文章 0 订阅

HDU 4763 Theme Section(KMP:后缀与前缀)

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

题意:给你一个字符串T,要你在中间找一段连续的串,使得该串与T的前缀相同,并且和T的后缀相同.(但是不重叠)

分析:

       首先我们要知道KMP算法可以用来求T串的next[i],next[i]=x表示以第i-1字符结尾的后缀 与T串前缀的最大匹配长度为x.

       目标串的长度为len,则len<=m  (m==strlen(T)/3).且len=min(len,next[m]),然后我们从第1号(0号开始计数)字符开始循环到第n-2号字符,利用当前字符的next值可以知道以当前字符的前一个字符为结尾的后缀最多能匹配T的前缀长度,在这个扫描过程中,我们求出合法(即不重叠的)的最大要求段长,且这个段长肯定<=len.

AC代码:

#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
char T[1000000+1000];
int next[1000000+1000];
int n,m;
void getFail()
{
    next[0]=next[1]=0;
    for(int i=1;i<m;i++)
    {
        int j=next[i];
        while(j && T[i]!=T[j]) j=next[j];
        next[i+1]= (T[i]==T[j])?j+1:0;
    }
}
int main()
{
    while(scanf("%d",&n)==1)
    {
        while(n--)
        {
            scanf("%s",T);
            m=strlen(T);
            getFail();
            int len = min(m/3 , next[m]);
            if(len==0)
            {
                printf("0\n");
                continue;
            }
            int max_len=0;
            for(int i=2;i<m;i++)
            {
                if(next[i]>len)continue;
                else if(next[i]>max_len)//可能可行
                {
                    int len1=min(i/2 , next[i]);//求出i-1的后缀与T的前缀的最大不重叠公共部分
                    if(len1>max_len && m-len1>=i)//判断T的长len1的后缀是不是已经延伸到了i-1位置,如果是,那么就重叠了
                        max_len=len1;
                }
            }
            printf("%d\n",max_len);
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值