HDU 4300 扩展KMP

题目链接

题意:

给两个字符串,第一个字符串是表示明文转密文转换方式,第二个字符串是密文和明文综合体,密文一定完整明文可能缺失,现在要求将缺失部分的明文复原且使得复原的字符串尽量短。

思路:

考虑明密文匹配可以发现问题实际上就是一个前后缀匹配问题。将字符串S全部视为明文以明文转密文的形式转化成字符串T,以T为母串(想要T的后缀)S为子串(想要S的前缀)进行扩展KMP匹配。

C++代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100010;

char S[maxn],T[maxn],MM[30],CC[30];
int Next[maxn],Ex[maxn];

void GetNext( char *s , int *Next )
{
    int c = 0,len = strlen(s);
    Next[0] = len;
    while ( s[c]==s[c+1]&&c+1<len ) c++;
    Next[1] = c;
    int po = 1;
    for ( int i=2 ; i<len ; i++ )
    {
        if ( Next[i-po]+i<Next[po]+po )
            Next[i] = Next[i-po];
        else
        {
            int t = Next[po]+po-i;
            if ( t<0 ) t = 0;
            while( i+t<len&&s[t]==s[i+t] ) t++;
            Next[i] = t;
            po = i;
        }
    }
}

void ExKmp( char *s1 , char *s2 , int *Next , int *Ex )
{
    int c = 0,len = strlen(s1),l2 = strlen(s2);
    GetNext( s2 , Next );
    while( s1[c]==s2[c]&&c<len&&c<l2 ) c++;
    Ex[0] = c;
    int po = 0;
    for ( int i=1 ; i<len ; i++ )
    {
        if ( Next[i-po]+i<Ex[po]+po )
            Ex[i] = Next[i-po];
        else
        {
            int t = Ex[po]+po-i;
            if ( t<0 ) t = 0;
            while( i+t<len&&t<l2&&s1[i+t]==s2[t] ) t++;
            Ex[i] = t;
            po = i;
        }
    }
}

int main()
{
    int Cas; scanf ( "%d" , &Cas );
    while ( Cas-- )
    {
        scanf ( "%s%s" , MM , S );
        int len = strlen(S);
        for ( int i=0 ; i<26  ; i++ )
            CC[MM[i]-'a'] = 'a'+i;
        for ( int i=0 ; i<len ; i++ )
            T[i] = MM[S[i]-'a'];
        T[len] = '\0';
        ExKmp( T , S , Next , Ex );
        int ans = len,sta = (len%2==0)?len/2:len/2+1;
        for ( int i=sta ; i<len ; i++ )
            if ( Ex[i]+i==len ) ans = min( ans , i );
        for ( int i=0 ; i<ans ; i++ )
            printf ( "%c" , S[i] );
        for ( int i=0 ; i<ans ; i++ )
            printf ( "%c" , CC[S[i]-'a'] );
        printf ( "\n" );
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/game_acm/article/details/81006286