题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4300
题目意思真的非常难读懂。
题意:给定两组字符串,第一组仅仅有26个字符表相应明文中a,b,c,d....z能够转换第一个,第二个...第26个字符变成密文,
第二组字符串是给定的密文+明文,明文可能不完整(缺失或没有),叫你补完且整个密文+明文是最短的
假设有多种明文则取最大的明文。
解题思路就是将前一半一定是密文的字符装换成明文。然后+后面的字符,从后往前匹配,匹配小于等于长度一半的最长前缀;
#include<map> #include<iostream> #include<cstdio> #include<cmath> #include<stack> #include<cstring> #include<set> #include<vector> #include<algorithm> #define LL long long #define inf 1<<30 #define s(a) scanf("%d",&a) #define CL(a,b) memset(a,b,sizeof(a)) using namespace std; const int N=200005; int n,m; char a[N],b[N]; char num[N]; char c[N]; int nnext[N]; void get_nnext(char *a,int len) { int j=-1,i=0; nnext[0]=-1; while(i<len){ if(j == -1 || a[i] == a[j]) nnext[++i]=++j; else j=nnext[j]; } } int main() { int t; cin>>t; while(t--){ cin>>a>>b; int len=strlen(b),k=len; for(int i=0;i<26;i++) num[a[i]-'a']='a'+i; for(int i=0;i<(len+1)/2;i++) c[i]=num[b[i]-'a']; // 将前一部分转换成密文。 for(int i=(len+1)/2;i<=len;i++) c[i]=b[i]; // 拼接后一部分明文; get_nnext(c,len); while(nnext[k]>len/2) k=nnext[k]; // 从后往前匹配;寻找长度小于len的最长前缀; cout<<b; for(int i=nnext[k];i<len-nnext[k];i++) cout<<num[b[i]-'a']; // 输出还不够的字符串。须要注意点的是这里输出的解密的字符,而不能直接用c[i]; cout<<endl; } return 0; }