HDU - 4300 Clairewd’s message (kmp)

Clairewd’s message

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6891    Accepted Submission(s): 2594


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
 

 

Author
BUPT
 

 

Source
 

 

Recommend
zhuyuanchen520
 
题目大意:先给出一段a-z对应的密文,第二行再给出一段密文+部分明文,要求输出密文+明文
 
解题思路:碰到字符串匹配的问题首先想到的就是kmp。整体思路就是讲第二行的字符串全当成明文翻译成密文,这样得到的字符串就是一段无意义的+之前部分明文对应的密文。然后利用kmp进行匹配,统计部分明文的数量,然后翻译输出就可以了。(学长的思路,没看其它的解题报告,自己完完整整做的第一道kmp题目。。想想就刺激)
做的时候先是用map<char,char>来存储明文密文对应的关系,后来发现要么明文转换成密文麻烦,要么密文翻译成明文麻烦,所以用了两个map,m是明文->密文,m2是密文->明文。
(因为本人没啥基础。。刚刚设计算法这一类,可能有很多地方写的太麻烦。。下面贴代码)
 
#include<cstdio>
#include<cstring>
#include<map>
using namespace std;
const int maxn=1e5+5;
int Next[maxn];
char s[maxn],ss[maxn],a[maxn];
map<char,char> m,m2;

void getNext() //构建next数组,直接套模板
{
    int i=0,j=-1;
    Next[0] = 0;
    Next[1] = 0;
    int l = strlen(s);
    for(i=1;i<l;i++)
    {
        int j=Next[i];
        while(j&&s[j]!=s[i]) j=Next[j];
        if(s[i]==s[j])
        {
            Next[i+1] = j+1;
        }
        else
        {
            Next[i+1] = 0;
        }
    }
}

int kmp()
{
    getNext();
    int j = 0,i=0;
    int ll = strlen(ss);
    int l = strlen(s);
/*    for(int i=0;i<ll;i++)
    {
        printf("%c",ss[i]);
    }
    printf("\n");
    for(int i=0;i<l;i++)
    {
        printf("%c",s[i]);
    }
    printf("\n");
    for(int i=0;i<=l;i++)
    {
        printf("%d",Next[i]);
    }
    printf("\n");
*/    for(int i=0;i<ll;i++)
    {
        while(j&&s[j]!=ss[i]) j=Next[j];
        //printf("ss[%d]-%c s[%d]-%c\n",i,ss[i],j,s[j]);
        if(s[j]==ss[i])
        {
            j++;
        }
        if(i==ll-1) //匹配进行到最后一个,返回j,j即为原字符串中明文数量
        {
            //printf("%d\n",j);
            return j;
        }
    }
    return 0;
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s",a);
        scanf("%s",s);
        int l = strlen(a);
        for(int i=0;i<l;i++)
        {
            m['a'+i] = a[i];       //m[明文] = 密文
            m2[a[i]] = 'a'+i;      //m2[密文] = 明文
        }
        l = strlen(s);
        int k=0;
        for(int i=(l+1)/2;i<l;i++) //因为密文肯定完整,所以l的前半部分肯定是密文,不用转换
        {
            ss[k++] = m[s[i]];
        }
        ss[k] = '\0';
        int End = kmp();
        End = l-End;//前面密文与明文分割的标志
        for(int i=0;i<End;i++)
        {
            printf("%c",s[i]);
        }
        for(int i=0;i<End;i++)
        {
            printf("%c",m2[s[i]]);
        }
        printf("\n");
    }
}

 

posted @ 2017-08-09 17:45  GoesOn  阅读(189)  评论(0编辑  收藏  举报