题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4300
题目大意:题目大意就是给以一段字符xxxxzzz前面x部分是密文z部分是明文,但是我们不知道是从哪里将密文和明文分开的,
密文是完整的,明文可能是不完整的,需要你补全,使得明文长度尽可能短。
解题思路:
因为密文至少占一半长度,所以从mid~len先假设为明文,然后将明文
转成密文求出nxt[len](nxt[len]<=len-nxt[eln],不断递归nxt[len]直到满足条件)即为明文长度。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e6+; int nxt[N];
char s[],pass[],text[N];//s将明文转密文,pass将密文转明文 void getnext(char *p,int m){
int i,j;
i=,j=nxt[]=-;
while(i<m){
while(j!=-&&p[i]!=p[j])
j=nxt[j];
nxt[++i]=++j;
}
} int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%s%s",s,text);
int len=strlen(text);
int mid=(len+)/;
for(int i=;i<;i++){
pass[s[i]-'a']=i+'a';
}
for(int i=mid;i<len;i++){
text[i]=s[text[i]-'a'];
}
getnext(text,len);
int res=nxt[len];
//明码长度res不能超过密码
while(res!=-){
if(res<=len-res)
break;
res=nxt[res];
}
for(int i=mid;i<len;i++){
text[i]=pass[text[i]-'a'];
}
printf("%s",text);
for(int i=res;i<len-res;i++){
printf("%c",pass[text[i]-'a']);
}
puts("");
}
return ;
}