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 another one according to a conversion table.
    Unfortunately, GFW(someone's name, not what you just think about) has detected their action. He also got their conversion table by some unknown methods before. Clairewd was so clever and vigilant that when she realized that somebody was monitoring their action, she just stopped transmitting messages.
    But GFW knows that Clairewd would always firstly send the ciphertext and then plaintext(Note that they won't overlap each other). But he doesn't know how to separate the text because he has no idea about the whole message. However, he thinks that recovering the shortest possible text is not a hard task for you.
    Now GFW will give you the intercepted text and the conversion table. You should help him work out this problem.

 

Input

The first line contains only one integer T, which is the number of test cases.
Each test case contains two lines. The first line of each test case is the conversion table S. S[i] is the ith latin letter's cryptographic letter. The second line is the intercepted text which has n letters that you should recover. It is possible that the text is complete.

Hint
Range of test data: T<= 100 ; n<= 100000;
 

Output

For each test case, output one line contains the shorest possible complete text.

 

Sample Input

2
abcdefghijklmnopqrstuvwxyz
abcdab
qwertyuiopasdfghjklzxcvbnm
qwertabcde

Sample Output

abcdabcd
qwertabcde

 

题意:破译密码。给一个加密表,分别对应a到z加密后的字母。再给一个字符串,为全部的密文+原文的一部分(也可能是全部)。也就是说这个字符串把密文和原文连在一起了,还不全,要求补齐串使满足全部密文+全部原文,并且这个串尽量短。

思路:由于密文一定全给出了,所以暴力的做法就是从中间开始向后检测,当后面的串加密后与前面串的对应前缀吻合,破译就成功了。

   想到这就有点熟悉.....主串后缀和模式串前缀.......可以用拓展kmp了。感觉其实把原串再加密或者解密都行,下面的代码是解密,然后得到一个前面原文后面无所谓是什么的串,作为模式串和原串跑一次拓展kmp,得到extend数组,从前往后找满足条件的ex,找到就跳出。条件为前面串长度大于等于ex(原串密文一定比原文长),并且ex和这个长度相加等于主串长(这样才是后缀)。

代码:

#include<bits/stdc++.h>
#define FastIO ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
#define inf 0x3f3f3f3f
#define rep(i,a,b) for(ll i=a;i<b;i++)
#define repp(i,a,b) for(ll i=a;i<=b;i++)
#define rep1(i,a,b) for(ll i=a;i>=b;i--)
#define mem(gv) memset(gv,0,sizeof(gv))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define QAQ 0
#define miaojie1
#ifdef miaojie
  #define dbg(args...) do {cout << #args << " : "; err(args);} while (0)
#else
  #define dbg(...)
#endif
void err() {std::cout << std::endl;}
template<typename T, typename...Args>
void err(T a, Args...args){std::cout << a << ' '; err(args...);}

using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pLL;
const int mod=1e9+7;
const int maxn=1e6+22;

int nxt[maxn],ex[maxn]; 
void GETNEXT(char *str)
{
    int i=0,j,po,len=strlen(str);
    nxt[0]=len;
    while(str[i]==str[i+1]&&i+1<len)
    i++;
    nxt[1]=i;
    po=1;
    for(i=2;i<len;i++)
    {
        if(nxt[i-po]+i<nxt[po]+po)
        nxt[i]=nxt[i-po];
        else
        {
            j=nxt[po]+po-i;
            if(j<0)j=0;
            while(i+j<len&&str[j]==str[j+i])
            j++;
            nxt[i]=j;
            po=i;
        }
    }
}

void EXKMP(char *s1,char *s2)
{
    int i=0,j,po,len=strlen(s1),l2=strlen(s2);
    GETNEXT(s2);
    while(s1[i]==s2[i]&&i<l2&&i<len)
    i++;
    ex[0]=i;
    po=0;
    for(i=1;i<len;i++)
    {
        if(nxt[i-po]+i<ex[po]+po)
        ex[i]=nxt[i-po];
        else
        {
            j=ex[po]+po-i;
            if(j<0)j=0;
            while(i+j<len&&j<l2&&s1[j+i]==s2[j])
            j++;
            ex[i]=j;
            po=i;
        }
    }
}

int T;
char s1[maxn],s2[maxn],h[230],ha[230];

int main(){
    scanf("%d",&T);
    while(T--){
        mem(s2); mem(h); mem(ha);
        scanf("%s%s",h,s1);
        int l1=strlen(s1);
        rep(i,0,26){
            ha[h[i]]=i+97;
        }
        rep(i,0,l1){
            s2[i]=ha[s1[i]];
        }
        EXKMP(s1,s2);
        int st=l1;
        rep(i,0,l1){
            if(i+ex[i]==l1 && i>=ex[i]){
                st=i;
                break;
            }
        }
        rep(i,0,st){
            s2[i]=s1[i];
            s2[i+st]=ha[s1[i]];
        }
        printf("%s\n",s2);
    }
    return QAQ;
}

 

posted on 2019-05-07 11:30  喵杰  阅读(123)  评论(0编辑  收藏  举报