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\n",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]='\0';
        printf("Case %d: ",++ff);
        Ekmp();
    }
}

 

posted @ 2015-08-13 16:28  sweat123  阅读(126)  评论(0编辑  收藏  举报