• hdu 3336 Count the string


          之前发现把题目的网页复制过来显的文章不太好,以后就不这么做了。杭州回来跟死了一样,发誓我要踏踏实实一步一步来。

          这个题是kmp的题,题目意思大概是对于原串中的每个前缀,找这个前缀在原串中出现过几次,对每个前缀都这么做,并用一个计数器来累加,最后要输出的就是这个结果%10007。这个题我tle了一次,主要是现在已经懒得算什么时间复杂度了,之前赛场上我队友非要n^2搞一个一百亿的数据量,我无语到吐血。。。

    tle代码:主要思想就是搞出来每个前缀并与原串进行KMP,时间复杂度不是很清楚,反正是挂掉了。后来自己胡乱想了一个想法,就是next数组搞出来的是前后缀问题,那么我就可以考察next数组,看对于其中的每一位会用它进行几次匹配。自己瞎想的,说不清楚,看之后的ac代码哇。

    View Code
    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    
    using namespace std;
    
    const int maxn=200000+5;
    
    char s[maxn];
    string str;
    int n,ans,len,next[maxn];
    
    void init()
    {
        ans=0;
        memset(s,0,(n+5)*sizeof(char));
    }
    
    void data_in()
    {
        getchar();
        scanf("%s",s);
    //    cout<<s<<endl;
    }
    
    void get_next()
    {
        int i=0,j=-1;
        next[0]=-1;
        while(i<len)
        {
            if(j==-1||s[i]==s[j])
                i++,j++,next[i]=j;
            else
                j=next[j];
        }
    }
    
    void KMP()
    {
        int j=-1;
        for(int i=0;i<len;i++)
        {
            while(j>-1&&str[j+1]!=s[i])
                j=next[j];
            if(str[j+1]==s[i]) j++;
            if(j==str.length()-1)
            {
                ans++;
                j=next[j];
            }
        }
    }
    
    void cal()
    {
        len=strlen(s);
        get_next();
    //    for(int i=0;i<=len;i++)
    //        cout<<next[i]<<endl;
    //    cout<<endl;
        for(int i=0;i<len;i++)
        {
            str="";
            for(int j=0;j<=i;j++)
                str+=s[j];
    //        cout<<str<<endl;
            KMP();
        }
        printf("%d\n",ans);
    }
    
    int main()
    {
        int ncas;
        scanf("%d",&ncas);
        while(ncas--)
        {
            scanf("%d",&n);
            init();
            data_in();
            cal();
        }
        return 0;
    }

    ac代码:

    View Code
    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    
    using namespace std;
    
    const int maxn=200000+5;
    
    char s[maxn];
    string str;
    int n,ans,len,next[maxn];
    
    void init()
    {
        ans=0;
        memset(s,0,(n+5)*sizeof(char));
    }
    
    void data_in()
    {
        getchar();
        scanf("%s",s);
    //    cout<<s<<endl;
    }
    
    void get_next()
    {
        int i=0,j=-1;
        next[0]=-1;
        while(i<len)
        {
            if(j==-1||s[i]==s[j])
                i++,j++,next[i]=j;
            else
                j=next[j];
        }
    }
    
    void cal()
    {
        len=strlen(s);
        get_next();
    //    for(int i=0;i<=len;i++)
    //        cout<<next[i]<<endl;
    //    cout<<endl;
        for(int i=len;i>=0;i--)
        {
            int j=i;
            while(next[j]!=-1)
            {
                ans++;
                j=next[j];
            }
        }
        printf("%d\n",ans%10007);
    }
    
    int main()
    {
        int ncas;
        scanf("%d",&ncas);
        while(ncas--)
        {
            scanf("%d",&n);
            init();
            data_in();
            cal();
        }
        return 0;
    }

    以后会每天都来博客转转,在我的那本书:柔性字符串匹配,回来之前或者回来以后,我都会接着把kmp,字典树,ac自动机,后缀自动机的题目一一找来做,自己先思考,是在做不出再去百度题解。我相信自己,虽然我已经想好了要放弃了,但还在坚持,因为我该做的还没有做完,内心深处给自己布置的那几本书还没有看完。总之就一切跟着刷题转。我qq405948382,有兴趣的朋友一起哇,我是菜鸟,求组队,但是不求虐,伤不起了!

  • 相关阅读:
    mysql 8.x 忘记密码
    sqlite
    公租房查询记录
    idea 常用快捷键总结
    vue h5项目中上传图片时保存之后显示不全
    微信小程序开发中使用npm命令快速添加页面
    【Luogu7816】「Stoi2032」以父之名
    【XSY3657】 因数分解
    Min_25筛学习笔记
    拉格朗日反演学习笔记
  • 原文地址:https://www.cnblogs.com/RainingDays/p/2760605.html
Copyright © 2020-2023  润新知