KMP Theme Section HDU

来源:互联网 发布:javascript重定向页面 编辑:程序博客网 时间:2024/05/22 06:15

这个题开始还没有觉得难。然后今天做了一下,发现这个很容易超时啊,如果不是先前后判断再去判断中间的。

#include <iostream>#include <cstring>#include <algorithm>#include <cstdio>#include <cmath>using namespace std;const int maxn = 1e6+10;char s[maxn],p[maxn],a[maxn];int Next[maxn];int vis[maxn];int ans=0;int gg=0;void GetNext(char *p){    memset(Next,0,sizeof(Next));    Next[0]=-1;    int k=-1;    int i=0;    int plen=strlen(p);    while(i<plen-1)//可以有重叠部分,改为plen-1,就不能啦    {        if(k==-1||p[i]==p[k])        {            k++;            i++;            Next[i]=k;//下一个的之前的最大前缀后缀        }        else k=Next[k];    }}int kmp(char *s,char *p){    int i=gg,j=0;    int slen=strlen(s);    while(i<slen-gg)    {        if(j==-1||p[j]==s[i])        {            i++;            j++;        }        else j=Next[j];        if(j==gg) {ans++;j=0;}    }     if(ans>=1)     {        return 1;     }    return 0;}int main(){    int n;    scanf("%d",&n);    while(n--)    {        scanf("%s",s);        int slen=strlen(s);        gg=0;        GetNext(s);        int flag=0,flag1=0;        for(gg=slen/3;gg>=1;gg--)        {             ans=0,flag1=0;             int i=0;            for(int j=slen-gg;j<slen;j++)            {                if(s[j]!=s[i++]) {flag1=1;break;}            }            if(flag1) {continue;}            if(kmp(s,s))            {                flag=1;                break;            }        }        if(flag)        printf("%d\n",gg);        else printf("0\n");    }    return 0;}
原创粉丝点击