题目大意:多组数据
第一行是一个含有26个字母的字符串,即翻译表,表示字母表(a、b、c……)中第i个字母对应的密文是s1[i]
第二行是一个另一个字符串s3,前面为密文后面为明文,密文一定是完整的, 明文可能不完整或没有
输出完整的密文和完整的明文
那么我们就把s3全部当做密文,根据翻译表s1全部翻译成明文s2,
这样,原来s3前面的密文就变成了明文,后面的明文变成什么对我们没有影响
显然,此时s2前面明文部分与s3的后面的明文部分应该是相同的
所以,我们应采用扩展kmp的方法,
将s3看做母串S,s2看做子串T,进行扩展kmp
从 len/2开始枚举,找到第一个i+exten[i]-1=len 且 i>=extend[i] 的位置作为明文的第一个字母,之前的即为密文,对应的即为明文
注意各种特例及细节:
1、可能没有明文,那么此时i会停止在len位置,即s3[1~len]全为密文而不是i之前的子串,所以我们在通过上面的方法确定出i位置后,判断s3[i]对应的密文与s3[1]是否相等,如果相等即s3[1~i-1]为密文,否则s3[1~i]为密文
2、密文的长度一定不小于len/2,在判断s3[i]对应的密文与s3[1]是否相等时,恰好相等,但是i-1
3、对于长度为1的情况的特判
总之不注意细节各种崩溃,不注意边界的特判各种坑,非常感谢讨论区倩同学提供的数据 orz
7
qwertyuiopasdfghjklzxcvbnm
qwert
qwertyuiopasdfghjklzxcvbnm
qwerta
qwertyuiopasdfghjklzxcvbnm
q
abcdefghijklmnopqrstuvwxyz
aaaa
abcdefghijklmnopqrstuvwxyz
aaa
abcdefghijklmnopqrstuvwxyz
aa
abcdefghijklmnopqrstuvwxyz
a
代码:
var
t,len :longint;
s1,s2,s3,ans :ansistring;
i,j,k :longint;
ch :char;
next,extend :array[0..100010] of longint;
procedure get_next;
var
a,p,l:longint;
j,k:longint;
begin
next[1]:=len;a:=0;
while (a+2<=len) do
if (s2[a+1]=s2[a+2]) then inc(a) else break;
next[2]:=a;a:=2;
//
for k:=3 to len do
begin
p:=a+next[a]-1;l:=next[1+k-a];
if (k+l-1p then a:=k;
end;
end;
end;
procedure get_extend;
var
a,p,l:longint;
j,k:longint;
begin
get_next;
a:=0;
while (a+1<=len) do
if (s2[a+1]=s3[a+1]) then inc(a) else break;
extend[1]:=a;a:=1;
//
for k:=2 to len do
begin
p:=a+extend[a]-1;l:=next[1+k-a];
if (k+l-1
p then a:=k;
end;
end;
end;
begin
readln(t);
while (t>0) do
begin
dec(t);
fillchar(next,sizeof(next),0);
fillchar(extend,sizeof(extend),0);
readln(s1);
readln(s3);
len:=length(s3);
if len=1 then
begin
write(s3);
for i:=1 to 26 do
if s3[1]=s1[i] then
begin
writeln(chr(96+i));break;
end;
end else
begin
s2:='';
for i:=1 to len do
for k:=1 to 26 do
if (s3[i]=s1[k]) then
begin
s2:=s2+chr(96+k);break;
end;
get_extend;
//
for i:=len div 2 to len do
if (i+extend[i]-1=len) and (i>=extend[i]) then break;
ch:=s1[ord(s3[i])-96];
if (ch=s3[1]) and ((i-1)*2>=len) then
begin
ans:=copy(s3,1,i-1);
ans:=ans+copy(s2,1,i-1);
end else
begin
ans:=copy(s3,1,i);
ans:=ans+copy(s2,1,i);
end;
writeln(ans);
end;
end;
end.
——by Eirlys