hdu4300 Clairewd’s message(KMP)

来源:互联网 发布:网络禁书40本打包下载 编辑:程序博客网 时间:2024/05/16 19:11

这题描述简直惊人。其实就是说先给你一个密码表。然后给你一个不一定完整的串。原串满足前一半是密码,后一半是明码。要求你最小的补全这个串。首先我们要明确:设给的串长度为len,则1...(len+1)/2的字母一定是密码。我们可以把这一部分作为模式串,去匹配后面的串。(当然因为我们假定后面的串都是明码,所以我们要把后面的串翻译成密码来匹配)。我们假设最后一位匹配到了模式串的第k位。则说明1..len-k都是密码。我们按此输出原串即可。注意别忘了加\0,害我WA了好久。打算一会再写个exkmp的补上。。

#include <cstdio>#include <cstring>#define N 100010int tst,n,fail[N];char a[255],b[255],s[N<<1],s2[N];inline void getfail(int m){int k=0;fail[1]=0;for(int i=2;i<=m;++i){while(k&&s[k+1]!=s[i]) k=fail[k];if(s[k+1]==s[i]) ++k;fail[i]=k;}}int main(){//freopen("a.in","r",stdin);scanf("%d",&tst);while(tst--){n=0;scanf("%s%s",a+'a',s+1);int len=strlen(s+1);for(int i='a';i<='z';++i) b[a[i]]=i;for(int i=(len+1)/2+1;i<=len;++i) s2[++n]=a[s[i]];getfail((len+1)/2);int k=0;for(int i=1;i<=n;++i){while(k&&s[k+1]!=s2[i]) k=fail[k];if(s[k+1]==s2[i]) ++k;}int m=len;for(int i=k+1;i<=len-k;++i) s[++m]=b[s[i]];s[++m]=0;//别忘了加\0 puts(s+1);}return 0;}


原创粉丝点击