• HDU 2087 HDU 1867 KMP标准模板题


    贴两道题,其中HDU2087是中文题,故不解释题目,

    思路是,一发KMP,但是特别处理最后一位的失配边为0,这样就可以保证“判断完成但是不多判断”。

    第二题,很毒瘤的题,要求求出,给定字符串A,B能够缠到一起组成的子字符串长度“长度较小且字典序较小”的一个。。。。要求,假设str1+str2组成答案,则str1的后缀和str2的前缀中相同的部分,只出现一次。。于是做法就是,两法KMP,特判答案咯。。。然而。。。。此题。。最有难度的地方是读懂提。。。。看了别人的提解读懂得。。。。

    2087AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    
    const long long MAXN=1233;
    long long f[MAXN];
    char str1[MAXN];
    long long len1;
    char str2[MAXN];
    long long len2;
    
    bool init()
    {
        cin>>str1;
        if(str1[0]=='#')return false;
        cin>>str2;
        len1=strlen(str1);
        len2=strlen(str2);
        f[0]=0;
        f[1]=0;
        for(int i=1;i<len2;++i)
        {
            int j=f[i];
            while(j&&str2[i]!=str2[j])j=f[j];
            f[i+1]= str2[i]==str2[j]? j+1:0;
        }f[len2]=0;
        return 1;
    }
    
    int main()
    {
        while(init())
        {
            long long summ=0;
            int j=f[0];
            for(int i=0;i<=len1;++i)
            {
                if(j==len2)summ++;
                while(j&&str1[i]!=str2[j])j=f[j];
                j= str1[i]==str2[j]? j+1:0;
            }cout<<summ<<"
    ";
        }
        
    }

    1867AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    const long long MAXN=100233;
    class str
    {
        public:
            int f[MAXN];
            char s[MAXN];
            int len;
    };
    str s1,s2;
    string ans1,ans2;
    void init()
    {
        s1.f[0]=0;s1.f[1]=0;
        s2.f[0]=0;s2.f[1]=0;
        ans1.clear();
        ans2.clear();
        s1.len=strlen(s1.s);
        s2.len=strlen(s2.s);
        for(int i=1;i<s1.len;++i)
        {
            int j=s1.f[i];
            while(j&&s1.s[i]!=s1.s[j])j=s1.f[j];
            s1.f[i+1]= s1.s[i]==s1.s[j] ? j+1:0;
        }
        for(int i=1;i<s2.len;++i)
        {
            int j=s2.f[i];
            while(j&&s2.s[i]!=s2.s[j])j=s2.f[j];
            s2.f[i+1]= s2.s[i]==s2.s[j] ? j+1:0;
        }
    }
    
    bool com(string &str1,string &str2)
    {
        int len=min(str1.length(),str2.length());
        for(int i=0;i<len;++i)
        {
            if(str1[i]!=str2[i])
            {
                if(str1[i]<str2[i])break;
                else return false;
            }
        }
        return 1;
    }
    int main()
    {
        cin.sync_with_stdio(false);
        while(cin>>s1.s>>s2.s)
        {
            init();
            int j=0;
            for(int i=0;i<s1.len;++i)
            {
                ans1.push_back(s1.s[i]);
                while(j&&s1.s[i]!=s2.s[j])j=s2.f[j];
                j= s1.s[i]==s2.s[j]? j+1:0;
            }
            for(;j<s2.len;++j)
            {
                ans1.push_back(s2.s[j]);
            }
            j=0;
            for(int i=0;i<s2.len;++i)
            {
                ans2.push_back(s2.s[i]);
                while(j&&s2.s[i]!=s1.s[j])j=s1.f[j];
                j= s2.s[i]==s1.s[j]? j+1:0;
            }
            for(;j<s1.len;++j)
            {
                ans2.push_back(s1.s[j]);
            }
            if(ans1<=ans2&&ans1.length()<=ans2.length())
            {
                cout<<ans1<<"
    ";
            }else cout<<ans2<<"
    ";
        }
        return 0;
    }
  • 相关阅读:
    thinkphp tp5 常用 functions
    nginx配置虚拟机 vhost 端口号 域名 区分虚拟机
    thinkphp tp5 模板 引擎 字符串 截取 函数 省略 显示
    C++运算符重载
    c++纯虚函数
    c++面向对象模型---c++如何管理类,对象以及它们之间的联系
    c++多态
    c++友元函数
    c语言的函数指针
    c++两种字符串赋值方式 并介绍 C语言下遍历目录文件的方式
  • 原文地址:https://www.cnblogs.com/rikka/p/7418734.html
Copyright © 2020-2023  润新知