题意为:给定一个翻译表,即第i个字母用哪个字母表示 再给一个串,里面前面为密文,后面为明文,密文一定是完整的,但明文不完整或可能没有,求这个完整的前面密文后面明文的串 把给定的串全部按表翻译为密文,这样例如样例 qwertabcde 翻译之后为: jvtkzqwert 可发现翻译后的后半部分与原传相同,把原串作为T串,翻译后的为S串,求B 题目要求求最短长度, 从B的一半开始, 当找到第一个满足 B[i]== len- i条件的,i即为第一个明文的位置,上代码:
//对了,貌似命名为next要和std命名空间中某个命名重复
//所以改为next1
#include <iostream>
#include<stdio.h>
#include <string.h>
using namespace std;
int next1[100005];
char str[27];
char s1[100005],s2[100005];
void getnext(char *t)
{
int i = 0,j = -1;
next1[0] = -1;
while(t[i])
{
if(j == -1 || t[i] == t[j])
{
i++;
j++;
next1[i] = j;
}
else
j = next1[j];
}
}
int kmp(char *s,char *t)
{
int i = 0,j = 0;
int slen =strlen(s),tlen = strlen(t);
getnext(t);
while(i<slen && j<tlen)
{
if(j == -1 || s[i] == t[j])
{
i++;
j++;
if(i == slen)
return j; //返回密文的长度
}
else
j = next1[j];
}
return 0;
}
int main()
{
int t,i,j;
cin >> t;
while(t--)
{
scanf("%s",str);
scanf("%s",s1);
int len = strlen(s1);
strcpy(s2,s1+(len+1)/2);
printf("%s",s1);
for(i = 0; s1[i]; i++)
{
for(j = 0; j<26; j++)
{
if(s1[i] == str[j])
{
s1[i] = 'a'+j;
break;
}
}
} //翻译的过程
int flag = kmp(s2,s1); //找到最大匹配
for(i = flag; i<len-flag; i++)
{
printf("%c",s1[i]);
}
cout << endl;
}
return 0;
}