HDU 4300 Clairewd‘s message 拓展KMP入门

HDU 4300 Clairewd‘s message 拓展KMP入门

题意

原题链接

这个题关键是要读懂题意,我做的时候就没有读懂,泪。题意是说给你的一个两个字符串,一个是26个字母密码表,依次对应替换的字母。然后给你一个字符串,这个字符串是不完整的(完整的应该是前半部分是加密的,后半部分是解密了的),然而,给你的字符串一定是加密的部分+一部分解密的部分(可以是全部,也可以是没有),让你求出最短的完整字符串,包括密文和明文;

解题思路

考虑给出的字符串S加密部分一定全部给出,所以给出的字符串的一半(最少是一半的长度)一定是加密的,也就是说给的字符串s = 密文+明文,我们把s全部按照密文进行转换得到字符串T =明文+密文,这样我们进行拓展KMPS作为母串,T作为子串(虽然他俩一样长),这样我们求S串的位置i处的extend[i]值,看看是不是等于len(S)-i(也就是S串左边的那部分长度,其实就是我们假设的密文长度)。

我也是看的题解做的这个题,看完后知道了,这个题难度不难,就是题意不好懂,理解后其实就是个拓展KMP的模板题,害,谁让自己太菜了呢?

代码实现

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<stack>
#include<queue>
#include<map>
#define hash hs //因为c++中hash好像是个特殊的标识符,但是下面我用了hash,这样改正比较简单
using namespace std;
const int MAXN=1e5+7;
int nx[MAXN], extend[MAXN];
char hash[27], op[27], str1[MAXN], str2[MAXN];
int t, n;
void get()
{
    int a=0, p=0, m=n;
    nx[0]=m;
    for(int i=1; i<m; i++)
    {
        if(i>=p || i+nx[i-a] >=p)
        {
            if(i>=p)
                p=i;
            while(p<m && str2[p] == str2[p-i])
                p++;
            nx[i] = p - i;
             a = i;
        }
        else nx[i] = nx[i-a];
    }
}
void getextend()
{
    int a=0, p=0;
    get();
    for(int i=0; i<n; i++)
    {
        if(i>=p || i+nx[i-a]>=p)
        {
            if(i>=p)
                p=i;
            while(p<n && p-i<n && str1[p] == str2[p-i])
                p++;
            extend[i] = p-i;
            a = i;
        }
        else extend[i] = nx[i-a];
    }
}
int main()
{
    scanf("%d", &t);
    while(t--)
    {
        scanf("%s %s", op, str1);
        for(int i=0; i<26; i++)
            hash[ op[i]-'a' ] = i + 'a';
        n = strlen(str1);
        for(int i=0; i<n; i++)
            str2[i] = hash[ str1[i]-'a' ];
        getextend();
        int div=n;
        for(int i=(n+1)/2; i < n; i++)
        {
            if(extend[i] == n - i && i >=extend[i])
            {
                div=i;
                break;
            }
        }
        for(int i=0; i<div; i++)
            printf("%c", str1[i]);
        for(int i=0; i<div; i++)
            printf("%c", str2[i]);
        printf("\n");
    }
    return 0;
}

原文地址:https://www.cnblogs.com/alking1001/p/12246939.html

时间: 2024-12-28 17:54:04

HDU 4300 Clairewd‘s message 拓展KMP入门的相关文章

HDU 4300 Clairewd&#39;s message ( 拓展KMP )

题意 : 给你一个包含26个小写字母的明文密文转换信息字符串str,第一个表示'a'对应的密文是str[0].'b'对应str[1]--以此类推.接下来一行给你一个另一个字符串,这个字符串由密文+明文组成,但是现在后面部分的明问可能有不完整的情况(也有可能缺失只包含密文),问你现在最少需要补充多多少个字符串才能使得字符串变成完整的满足==>密文+密文对应的明文 组成的字符串,将这个完整的字符串输出出来. 分析 : 冷静分析一下可以发现,在给出的残缺字符串中,前面的一半肯定是属于密文的!如果不是这

hdu 4300 Clairewd’s message(kmp/扩展kmp)

题意:真难懂.. 给出26个英文字母的加密表,明文中的'a'会转为加密表中的第一个字母,'b'转为第二个,...依次类推. 然后第二行是一个字符串(str1),形式是密文+明文,其中密文一定完整,而明文可能不完整(也可能没有). 求出最短的完整的字符串(密文+明文). 思路: 1.用kmp来做: 首先肯定的是,给定的串中明文长度一定小于等于密文.也就是说明文长度小于等于总长的一半. 于是,取总长的后一半作为主串,然后把串反翻译一遍得到str2,然后用str2与str1的后一半进行匹配.首次把st

hdu 4300 Clairewd’s message (KMP)

给定一个翻译表,即第i个字母用哪个字母表示 再给一个串,里面前面为密文,后面为明文,密文一定是完整的,但明文不完整或可能没有 求这个完整的前面密文后面明文的串 # include <stdio.h> # include <algorithm> # include <string.h> using namespace std; int len; int next[100010]; char a1[100010],a2[100010],a3[100010]; void Ge

HDU 4300 Clairewd’s message(初遇拓展KMP)

昨晚一不小心学了拓展KMP,被虐了一晚,最终是这份资料救了我...http://wenku.baidu.com/view/8e9ebefb0242a8956bece4b3.html 说得简单易懂. 然后学了kuangbin的模版: /* * 扩展KMP算法 */ //next[i]:x[i...m-1]与x[0...m-1]的最长公共前缀 //extend[i]:y[i...n-1]与x[0...m-1]的最长公共前缀 void pre_EKMP(char x[],int m,int next[

hdu 4300 Clairewd’s message 字符串哈希

Clairewd’s message Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 10376    Accepted Submission(s): 3709 Problem Description Clairewd is a member of FBI. After several years concealing in BUPT,

hdu 4300 Clairewd’s message(详解,扩展KMP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4300 Problem Description Clairewd is a member of FBI. After several years concealing in BUPT, she intercepted some important messages and she was preparing for sending it to ykwd. They had agreed that ea

HDU 4300 Clairewd’s message(扩展KMP)

思路:extend[i]表示原串以第i开始与模式串的前缀的最长匹配.经过O(n)的枚举,我们可以得到,若extend[i]+i=len且i>=extend[i]时,表示t即为该点之前的串,c即为该点之前的str串,最后输出即可. #include<iostream> #include<cstdio> #include<cstring> #include<map> using namespace std; const int N=100010; char

HDU 4300 Clairewd’s message

Problem Description Clairewd is a member of FBI. After several years concealing in BUPT, she intercepted some important messages and she was preparing for sending it to ykwd. They had agreed that each letter of these messages would be transfered to a

题解报告:hdu 2087 剪花布条(KMP入门)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2087 Problem Description 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢? Input 输入中含有一些数据,分别是成对出现的花布条和小饰条,其布条都是用可见ASCII字符表示的,可见的ASCII字符有多少个,布条的花纹也有多少种花样.花纹条和小饰条不会超过1000个字符长.如果遇见#字符