HDU 4300 Clairewd’s message(扩展KMP)

来源:互联网 发布:python 字典生成式 编辑:程序博客网 时间:2024/05/21 11:18

HDU 4300 Clairewd’s message(扩展KMP)

http://acm.hdu.edu.cn/showproblem.php?pid=4300

题意:首先有一个字母的转换表,就是输入的第一行的字符串,就是'a'转成第一个字母,'b'转成转换表的第二个字母·······

然后下面一个字符串是密文+明文的形式的字符串。

就是说前后两段是重复的,只不过通过转换表转换了下。

而且后面一段可能不完整。我们现在要找到这个串可能的最短密文+明文.

分析:

       首先串S的最短密文+明文可能就是本身,也就是说S正好可以分成两段,前一段是密文可以通过转换表转成与后半段正好相同的明文.

且密文+明文的长度最长不会超过2*T.(即串S完全是密文)

       由于前半段是密文,后半段是明文.假设输入串为S,我们将S完全映射之后得到串T,然我们用串T作为模式串去匹配串S,调用扩展KMP算法,求出以S[i]为开头的前缀与串T的前缀最多匹配长度.那么只要有一个超过串S一半以上的位置的i,以s[i]为头的前缀与T前缀匹配到底,那么这个i就是S中明文的开始.(仔细想想是不是)

AC代码:

#include<cstdio>#include<algorithm>#include<cstring>#include<map>using namespace std;const int MAXN=100000+1000;char S[MAXN],T[MAXN];int B[MAXN],A[MAXN];int n,m;void EKMP(){    int j=0;    while(j+1<m && T[0+j]==T[1+j])        j++;    A[1]=j;    int k=1;    for(int i=2;i<m;i++)    {        int len=k+A[k]-1,L=A[i-k];        if(L<len-i+1)            A[i]=L;        else        {            j=max(0,len-i+1);            while(i+j<m && T[0+j] ==T[i+j])                j++;            A[i]=j;            k=i;        }    }    j=0;    while(j<n && j<m && S[0+j]==T[0+j])        j++;    B[0]=j;    k=0;    for(int i=1;i<n;i++)    {        int len=k+B[k]-1,L=A[i-k];        if(L<len-i+1)            B[i]=L;        else        {            j=max(0,len-i+1);            while(i+j<n && j<m && S[i+j]==T[j])                j++;            B[i]=j;            k=i;        }    }}int main(){    int kase;    scanf("%d",&kase);    while(kase--)    {        map<char ,char> mp;        char str[30];        scanf("%s%s",str,S);        int len1=strlen(str);        m=n=strlen(S);        for(int i=0;i<len1;i++)            mp[str[i]]=i+'a';        for(int i=0;i<n;i++)            T[i]=mp[S[i]];        T[n]=0;        EKMP();        int i;        for(i=(n+1)/2;i<n;i++)            if(i+B[i]==n)                break;        for(int j=0;j<i;j++)            printf("%c",S[j]);        for(int j=0;j<i;j++)            printf("%c",mp[S[j]]);        printf("\n");    }    return 0;}


0 0
原创粉丝点击