HDU4300
本题题意比较难读懂,题意为给你一段密文的映射方式和一段密文+明文的字符串,密文是完整的,而明文不一定是完整的,让你添加最少的字符使他变为完整的密文+明文
如果读懂题意,可以考虑给定字符串中密文长度一定是
>=len/2
>=
l
e
n
/
2
的,所以我们可以将后半段的字符均按照映射换为密文,然后找到最长的既在前缀中出现又在后缀中出现的子串,根据next数组的性质(如果不理解的可以去看我的KMP总结专题中的next数组性质2)不断递归next直到找到符合条件的
len
l
e
n
然后跳出即可,输出时要注意明文密文的转换
HDU4300代码
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stack>
using namespace std ;
const int maxn = 1e5+5;
int Next[maxn];
char str[maxn];
char str2[maxn];
char mo[maxn];
int dp[maxn];
int mm[30];
int nn[maxn];
int n1,n2;
void GetNext()
{
int i=0,j=-1;
while(i<n2)
{
if(j==-1||mo[i]==mo[j]) {++i,++j,Next[i]=j;}
else j=Next[j];
}
return ;
}
int ans[maxn];
int main()
{
int cnt;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%s%s",str,mo);
strcpy(str2,mo);
n2=strlen(mo);
n1=strlen(str);
for(int i=0;i<n1;i++)
{
mm[i]=str[i]-'a';
nn[str[i]-'a']=i;
}
for(int i=0;i<(n2+1)/2;i++)
{
mo[i]=nn[mo[i]-'a']+'a';
}
Next[0]=-1;
GetNext();
int ans=Next[n2];
while(ans>min((n2+1)/2,n2-(n2+1)/2))
{
ans=Next[ans];
}
for(int i=0;i<n2-ans;i++)
printf("%c",str2[i]);
for(int i=0;i<n2-ans;i++)
printf("%c",nn[str2[i]-'a']+'a');
printf("\n");
}
return 0;
}