hud 4300 扩展kmp
来源:互联网 发布:网络系统集成就业前景 编辑:程序博客网 时间:2024/04/27 23:52
题目大意:多组数据
第一行是一个含有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<len/2即i-1作为密文最短长度不成立,那么最短长度应该是i
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-1<p) then next[k]:=l else begin if p-k+1<0 then j:=0 else j:=p-k+1; while (k+j<=len) and (j+1<=len) do if (s2[k+j]=s2[j+1]) then inc(j) else break; next[k]:=j; if k+next[k]-1>p 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 extend[k]:=l else begin if p-k+1<0 then j:=0 else j:=p-k+1; while (j+k<=len) and (j+1<=len) do if (s3[j+k]=s2[j+1]) then inc(j) else break; extend[k]:=j; if k+extend[k]-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- hud 4300 扩展kmp
- hdu 4300 扩展KMP
- 扩展KMP
- 扩展KMP
- 扩展KMP
- 扩展KMP
- 扩展 KMP
- 扩展kmp
- 扩展KMP
- 扩展KMP
- 扩展KMP
- 扩展KMP
- 扩展KMP
- 扩展KMP
- 扩展KMP
- 扩展KMP
- 扩展KMP
- 扩展KMP
- RabbitMQ 客户端(for andorid)使用详解
- <select>中文乱码
- 使用listview,item的按钮点击改变按钮背景,点击其他条目按钮还原
- 如何在Ubuntu 14.04中利用Let's Encrypt保障Nginx安全
- WebRTC手记之初探
- hud 4300 扩展kmp
- 【iOS开发】iOS 组件化方案
- WebRTC手记之框架与接口
- ReactiveCocoa 和 MVVM 入门
- 索引
- BeagleBone Green Wireless 入门
- 扫端口
- WebRTC手记之本地视频采集
- leetcode-97. Interleaving String