• HDU 4300 Clairewd’s message KMP


    题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=4300


    这道题目的题意太难理解了。

    第一行给你26个字母的一段密文,对应明文是从a-z。

    第二行给你前面是密文后面是明文的字符串,密文一定是完整的,但是明文可能没有也可能都有。

    让你求最短的密文+明文。


    例一:abcdab

    最短密文:abcd,它对应的明文是abcd

    所以最短密文+明文为abcdabcd

    例二:qwertabcde

    最短密文:qwert,它对应的明文是abcde

    所以最短密文+明文为qwertabcde

    有点难理解。


    思路:明文的长度一定小于等于len/2,然后用后面的一半与对应的明文匹配

    比如第一个例子:用dab与abcdab最大匹配为t=2,说明有两个已经是明文,从t到len-t输出后面的即为未显示的明文,


    AC代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <cstdlib>
    #include <cmath>
    #include <vector>
    #include <list>
    #include <deque>
    #include <queue>
    #include <iterator>
    #include <stack>
    #include <map>
    #include <set>
    #include <algorithm>
    #include <cctype>
    using namespace std;
    
    typedef __int64 LL;
    const int N=100090;
    const LL II=1000000007;
    const int INF=0x3f3f3f3f;
    const double PI=acos(-1.0);
    
    char word[N],yi[26],mi[26],xh[N];
    int wlen,next[N];
    
    void getnext(char *p)
    {
        int j=0,k=-1;
        next[0]=-1;
        while(j<wlen)
        {
            if(k==-1||p[j]==p[k])
            {
                j++;    k++;
                next[j]=k;
            }
            else
                k=next[k];
        }
    }
    
    int kmp(char *text,char *word)
    {
        int i=0,j=0,tlen=strlen(text);
        while(i<tlen)
        {
            if(j==-1||text[i]==word[j])
                j++,i++;
            else
                j=next[j];
        }
        return j;//返回母串后缀与模式串前缀最多有多少个重合
    }
    
    int main()
    {
        int i,j,T;
        scanf("%d",&T);
    	while(T--)
    	{
    	    scanf("%s%s",yi,word);
    	    printf("%s",word);
    	    for(i=0;i<26;i++)
                mi[yi[i]-'a']=i+'a';//密文对应的明文
            wlen=strlen(word);
            strcpy(xh,word+(wlen+1)/2);
            for(i=0;i<wlen;i++)
                word[i]=mi[word[i]-'a'];
            getnext(word);
            int t=kmp(xh,word);//明文重叠的部分
            int p=wlen-t;//还要输出的
            word[p]='';
            printf("%s
    ",word+t);//从t到p
    	}
    	return 0;
    }
    


  • 相关阅读:
    阅读任务
    自我介绍
    学习总结
    第十二周课程总结
    第十一周课程总结
    第十周课程总结
    第九周课程总结&实验报告(七)
    第四周课程总结&实验报告
    第3周Java编程总结
    学习总结
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3209206.html
Copyright © 2020-2023  润新知