hdu4300 Clairewd’s message(KMP)

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

#include <cstdio>
#include <cstring>
#define N 100010
int 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;
}
    原文作者:KMP算法
    原文地址: https://blog.csdn.net/Icefox_zhx/article/details/76020921
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞