3409: [Usaco2009 Oct]Barn Echoes 牛棚回声
3409: [Usaco2009 Oct]Barn Echoes 牛棚回聲
Time Limit:?3 Sec??Memory Limit:?128 MBSubmit:?57??Solved:?47
[Submit][Status][Discuss]
Description
奶牛們灰常享受在牛欄中哞叫,因?yàn)樗齻兛梢月牭剿齻冞杪暤幕匾簟km然有時(shí)候并不能完全聽到完整的回音。Bessie曾經(jīng)是一個(gè)出色的秘書,所以她精確地紀(jì)錄了所有的哞叫聲及其回聲。她很好奇到底兩個(gè)聲音的重復(fù)部份有多長。
輸入兩個(gè)字符串(長度為1到80個(gè)字母),表示兩個(gè)哞叫聲。你要確定最長的重復(fù)部份的長度。兩個(gè)字符串的重復(fù)部份指的是同時(shí)是一個(gè)字符串的前綴和另一個(gè)字符串的后綴的字符串。
我們通過一個(gè)例子來理解題目。考慮下面的兩個(gè)哞聲:
moyooyoxyzoooyzoooqyasdfljkamo第一個(gè)串的最后的部份"yzooo"跟第二個(gè)串的第一部份重復(fù)。第二個(gè)串的最后的部份"mo"跟第一個(gè)串的第一部份重復(fù)。所以"yzooo"跟"mo"都是這2個(gè)串的重復(fù)部份。其中,"yzooo"比較長,所以最長的重復(fù)部份的長度就是5。
Input
兩行: 每一行是1個(gè)字符串表示奶牛的哞聲或它的回聲。
?
Output
?
第一行: 包含一個(gè)單獨(dú)的整數(shù)表示輸入的2個(gè)字符串中,一個(gè)字符串的前綴和另一個(gè)字符串的后綴的最長的重復(fù)部份的長度。
?
Sample Input
abcxxxxabcxabcd
abcdxabcxxxxabcx
Sample Output
11"abcxxxxabcx"是第一個(gè)字符串的前綴和第二個(gè)字符串的后綴。
HINT
Source
Gold
?
題解:不知道bzoj啥時(shí)候冒出來一堆普及組的題目QAQ
要是想A的話太容易了,所以還是瞎搞搞來連連腦洞吧
方法一:直接\( O\left({N}^{2} \right)?\)瞎搞。。。(PS:不要問我為啥只有一層循環(huán),事實(shí)上copy的復(fù)雜度是O(N)的)
1 /************************************************************** 2 Problem: 3409 3 User: HansBug 4 Language: Pascal 5 Result: Accepted 6 Time:0 ms 7 Memory:416 kb 8 ****************************************************************/ 9 10 var 11 i,j,k,l,m,n:longint; 12 s1,s2,s3:ansistring; 13 function max(x,y:longint):longint; 14 begin 15 if x>y then max:=x else max:=y; 16 end; 17 begin 18 readln(s1); 19 readln(s2);l:=0; 20 for i:=max(length(s2)-length(s1)+1,1) to length(s2) do 21 begin 22 s3:=copy(s2,i,length(s2)+1-i); 23 if copy(s1,1,length(s2)+1-i)=s3 then 24 begin 25 l:=length(s2)+1-i; 26 break; 27 end; 28 end; 29 for i:=max(length(s1)-length(s2)+1,1) to length(s1) do 30 begin 31 s3:=copy(s1,i,length(s1)+1-i); 32 if copy(s2,1,length(s1)+1-i)=s3 then 33 begin 34 l:=max(l,length(s1)+1-i); 35 break; 36 end; 37 end; 38 writeln(l); 39 readln; 40 end.?
方法二:這是我第一反應(yīng)的做法(但是N<=80是什么節(jié)奏= =)——字符串哈希(哈希大法好OTL),于是瞎搞搞,很基礎(chǔ)的。。。(本人實(shí)測N<=3000000都能1s內(nèi)出來)
1 /************************************************************** 2 Problem: 3409 3 User: HansBug 4 Language: Pascal 5 Result: Accepted 6 Time:0 ms 7 Memory:4944 kb 8 ****************************************************************/ 9 10 const p=314159;q=951413; 11 var 12 i,j,k,l,m,n,x0,y0,x,y:longint; 13 list,a,b:array[0..5000000,1..2] of int64; 14 s1,s2:ansistring; 15 function max(x,y:longint):longint; 16 begin 17 if x>y then max:=x else max:=y; 18 end; 19 20 begin 21 list[0,1]:=1;list[0,2]:=1; 22 readln(s1); 23 readln(s2);l:=0; 24 n:=max(length(s1),length(s2))+1; 25 for i:=1 to n do 26 begin 27 list[i,1]:=(list[i-1,1]*p) mod q; 28 list[i,2]:=(list[i-1,2]*q) mod p; 29 end; 30 a[0,1]:=0;a[0,2]:=0; 31 for i:=1 to length(s1) do 32 begin 33 a[i,1]:=(a[i-1,1]+(list[i,1]*ord(s1[i])) mod q) mod q; 34 a[i,2]:=(a[i-1,2]+(list[i,2]*ord(s1[i])) mod p) mod p; 35 end; 36 b[0,1]:=0;b[0,2]:=0; 37 for i:=1 to length(s2) do 38 begin 39 b[i,1]:=(b[i-1,1]+(list[i,1]*ord(s2[i])) mod q) mod q; 40 b[i,2]:=(b[i-1,2]+(list[i,2]*ord(s2[i])) mod p) mod p; 41 end; 42 for i:=max(1,length(s1)-length(s2)+1) to length(s1) do 43 begin 44 j:=length(s1)-i+1; 45 x:=(list[i-1,1]*b[j,1]) mod q; 46 y:=(list[i-1,2]*b[j,2]) mod p; 47 x0:=((a[length(s1),1]-a[i-1,1]) mod q+q) mod q; 48 y0:=((a[length(s1),2]-a[i-1,2]) mod p+p) mod p; 49 if (x=x0) and (y=y0) then 50 begin 51 l:=j; 52 break; 53 end; 54 end; 55 for i:=max(1,length(s2)-length(s1)+1) to length(s2) do 56 begin 57 j:=length(s2)-i+1; 58 x:=(list[i-1,1]*a[j,1]) mod q; 59 y:=(list[i-1,2]*a[j,2]) mod p; 60 x0:=((b[length(s2),1]-b[i-1,1]) mod q+q) mod q; 61 y0:=((b[length(s2),2]-b[i-1,2]) mod p+p) mod p; 62 if (x=x0) and (y=y0) then 63 begin 64 l:=max(j,l); 65 break; 66 end; 67 end; 68 writeln(l); 69 readln; 70 end.?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/HansBug/p/4418659.html
總結(jié)
以上是生活随笔為你收集整理的3409: [Usaco2009 Oct]Barn Echoes 牛棚回声的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Dividing 多重背包 倍增D
- 下一篇: 对象水平对齐,并且按照竖直方向排列