zoukankan      html  css  js  c++  java
  • hdu4333 扩展KMP

    慢慢研究可以发现,可以用扩展kmp来求。由于扩展kmp的next[]只有一部分,当前位子前面那部分和母串的后部分,所以可以将字符串复制接在后面一次。

    先求如果next[]>0&&next[]!=len,那么只要考虑后面那位的大小比较。如果next[]>=len 那就是相同。如果next[]==0,就是没有相同的,直接比较开头。

    这样做还是会超时,我tle无数发。

    还要去掉重复的部分,题目要求不同的。所以求出循环部分,只要考虑一部分即可。

        //扩展kmp求最小循环节
        int kk;  // kk保存最短循环节  
        for(i=1; i<=len; ++i)
        {  
            if(i+next[i]>=len)
            {  
                kk = len%i ? len : i;  
                break;  
            }  
        }  
    #include<stdio.h>
    #include<string.h>
    #define maxn 100010
    char s[maxn],ss[maxn*2];
    int next[maxn*2],n[maxn];
    void getnext()
    {
        int i,j,len=strlen(ss),k;
        next[0]=len;
        i=0;
        while(i<len-1&&ss[i]==ss[i+1])
            i++;
        next[1]=i;
        int a=1;
        for(k=2;k<len;k++)
        {
            int p=a+next[a]-1;
            int l=next[k-a];
            if(k-1+l>=p)
            {
                int j=p-k+1>0?p-k+1:0;
                while(j+k<len&&ss[j+k]==ss[j])
                    j++;
                next[k]=j;
                a=k;
            }
            else next[k]=l;
        }
    }
    void Ekmp()
    {
        getnext();
        int i,j,len=strlen(s),k;
        int ansmin,ansequ,ansmax;
        ansmin=ansequ=ansmax=0;
        //扩展kmp求最小循环节
        int kk;  // kk保存最短循环节  
        for(i=1; i<=len; ++i)
        {  
            if(i+next[i]>=len)
            {  
                kk = len%i ? len : i;  
                break;  
            }  
        }  
        for(i=0;i<kk;i++)
        {
            if(next[i]==0)
            {
                if(ss[i]>ss[0])
                    ansmax++;
                else ansmin++;
            }
            else if(next[i]>=len)
            {
                ansequ++;
            }
            else 
            {
                if(ss[next[i]+i]>ss[next[i]])
                {
                    ansmax++;
                }
                else ansmin++;
            }
        }
        printf("%d %d %d
    ",ansmin,ansequ,ansmax);
    }
    int main()
    {
        int i,j,t,ff=0,len;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%s",s);
            len=strlen(s);
            int k=0;
            for(i=0;i<len;i++)
                ss[k++]=s[i];
            for(i=0;i<len;i++)
                ss[k++]=s[i];
            ss[k]='';
            printf("Case %d: ",++ff);
            Ekmp();
        }
    }
  • 相关阅读:
    淘宝客之 API调用实例讲解
    15个哲理小故事
    淘宝客之 淘宝客类目URL获取
    应广大淘宝客支持者 发布CHM API文档一份 鄙视官方没有离线文档
    淘宝客开发知识 开发前准备与基础知识
    富人和穷人间存在的十二个致命差异
    侧边栏
    半颗星星评分
    让DIV动起来
    软件项目开发过程中主要遇到的核心问题小结
  • 原文地址:https://www.cnblogs.com/sweat123/p/4727691.html
Copyright © 2011-2022 走看看