zoukankan      html  css  js  c++  java
  • hdu-4763(kmp+拓展kmp)

    题意:给你一个串,问你满足最大字串既是前后缀,也在字符串除去前后缀的位置中出现过;

    思路:我用的是拓展kmp求的前后缀,只用kmp也能解,在字符串2/3的位置后开始遍历,如果用一个maxx保存前2/3的最大的next(kmp),也就是最大字串的前后缀,在与拓展kmp的next[i]进行比较;

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #define maxn 1000500
    using namespace std;
    char t[maxn];
    int tlen;
    int next1[maxn];
    int exnext[maxn];
    void get_next()
    {
    int j=0,k=-1;next1[0]=-1;
    while(j<tlen)
    {
    if(k==-1||t[k]==t[j])
    next1[++j]=++k;
    else
    k=next1[k];
    }
    }
    void get_exnext()
    {
    int i=0,j,po;
    exnext[0]=tlen;
    while(t[i]==t[i+1]&&i+1<tlen)
    i++;
    exnext[1]=i;
    po=1;
    for(int i=2;i<tlen;i++)
    {
    if(exnext[i-po]+i<exnext[po]+po)
    exnext[i]=exnext[i-po];
    else
    {
    j=exnext[po]+po-i;
    if(j<0)
    j=0;
    while(i+j<tlen&&t[j]==t[j+i])
    j++;
    exnext[i]=j;
    po=i;
    }
    }
    }
    int main()
    {
    int tt;
    scanf("%d",&tt);
    while(tt--)
    { int ans=0;
    scanf("%s",t);
    tlen=strlen(t);
    if(tlen<=2)
    {
    printf("0 ");
    }
    else
    {
    get_next();
    get_exnext();
    int z=tlen/3;
    z=tlen-z;
    //cout<<z<<endl;
    int maxx=-1;
    for(int i=0;i<=z;i++)
    {
    maxx=max(next1[i],maxx);
    }
    // cout<<maxx<<endl;
    for(int i=z;i<tlen;i++)
    {
    if(maxx<next1[i])
    maxx=next1[i];
    if(exnext[i]<=maxx)//答案取拓展kmp的值,因为满足子串前后缀大的不一定满足原串的前后缀大;
    {
    ans=max(ans,exnext[i]);
    }
    }
    }
    printf("%d ",ans);

    }
    }

      

    ---恢复内容结束---

  • 相关阅读:
    STL常用容器☞String容器
    初识STL
    函数模板
    多态
    运算符重载
    友元
    对象的初始化和清理
    C++内存分区模型
    传值和传地址
    const的使用
  • 原文地址:https://www.cnblogs.com/huangdao/p/9450936.html
Copyright © 2011-2022 走看看