【問題描述】
資訊的明文是由0利1組成的非空序列。但在網路通訊中,為了資訊的安全性,常對明文進行加密,用密文進行傳輸。密文是由0、1和若干個密碼字母組成,每個密碼字母代表不同的01串,例如,密文=011a0bf00a01。密碼破譯的關鍵是確定每個密碼的含義。
經過長期統計分析,現在知道了每個密碼的固定長度,如今,我方又截獲了敵方的兩段密文s1和s2,並且知道s1=s2,即兩段密文代表相同的明文。你的任務是幫助情報人員對給定的兩段密文進行分析,看一看有多少種可能的明文。
【輸入檔案】
第1行: s1 (第1段密文)
第2行: s2 (第2段密文)
第3行: n (密碼總數, n<=26)
第4—n+3行: 字母i 長度i (密碼用小寫英文本母表示, 密碼長度<=100)
【輸出檔案】
m(表示有m種可能的明文)
【輸入輸出樣例】
encrypt.in
100ad1
cc14
a 2d 3
c 4b 50
encrypt.out
2【約束條件】
明文的長度<=10000
注意:如果兩個密文出現矛盾情況,則輸出0。
[size=x-large]【思路】樹狀[color=red]並查集[/color]應用
將需要相等的位置的合併,
統計有ans組,
每種2個情況,
乘法原理
[size=xx-large]var
p:array ['a'..'z']of record b,e,l:longint; c:boolean; end;
f,a1,a2:array [-2..10000] of longint;
s1,s2:ansistring;c:char;
n,i,l,j,x,y,ans,z,temp:longint;
function father(x:longint):longint; begin
if (f[x]=x)or(f[x]=0) then exit(f[x]) else
begin
f[x]:=father(f[x]);
father:=f[x];
end;
end;
procedure ex; begin
write(0); close(input);close(output);halt;
end;
begin
assign(input,'encrypt.in');reset(input);
assign(output,'encrypt.out');rewrite(output);
readln(s1);readln(s2);
readln(n);
for i:=1 to n do readln(c,p[c].l);
for i:=1 to length(s1) do if (s1[i]<>'1')and(s1[i]<>'0') then p[s1[i]].c:=true;
for i:=1 to length(s2) do if (s2[i]<>'1')and(s2[i]<>'0') then p[s2[i]].c:=true;
l:=2;
for c:='a' to 'z' do if p[c].c then
begin
p[c].b:=l;
inc(l,p[c].l);
p[c].e:=l-1;
end;
z:=l-1;
for i:=1 to l do f[i]:=i;
l:=0;
for i:=1 to length(s1) do
case s1[i] of
'1':begin inc(l);a1[l]:=1;end;
'0':begin inc(l);a1[l]:=0;end;
else
begin
for j:=p[s1[i]].b to p[s1[i]].e do
begin
inc(l);
f[j]:=j;
a1[l]:=j;
end;
end;end;
l:=0;
for i:=1 to length(s2) do
case s2[i] of
'1':begin inc(l);a2[l]:=1;if a1[l]=0 then ex; end;
'0':begin inc(l);a2[l]:=0;if a1[l]=1 then ex; end;
else
begin
for j:=p[s2[i]].b to p[s2[i]].e do
begin
inc(l);
f[j]:=j;
a2[l]:=j;
end;
end;end;
for i:=1 to l do
begin
x:=father(a1[i]);y:=father(a2[i]);
if x+y=1 then ex;
if x>y then f[x]:=y else f[y]:=x;
end;
ans:=0;f[1]:=1;
for i:=2 to z do
begin
temp:=father(f[i]);
if (temp<>1)and(temp<>0) then begin inc(ans); f[temp]:=0;end;
end;
writeln(1 shl ans);
close(input);close(output);
end.
並查集 並查集
本文參考了 挑戰程式設計競賽 和jennica的github題解 陣列版 int parent max n int rank max n void init int n int find int x else void union int x,int y else 結構體版 struct node ...
並查集入門(普通並查集 帶刪除並查集 關係並查集)
什麼是並查集?通俗易懂的並查集詳解 普通並查集 基礎並查集 例題 題解 how many tables problem description lh boy無聊的時候很喜歡數螞蟻,而且,還給每乙隻小螞蟻編號,通過他長期的觀察和記錄,發現編號為i的螞蟻會和編號為j的螞蟻在一起。現在問題來了,他現在只有...
並查集,帶權並查集
題意 ignatius過生日,客人來到,他想知道他需要準備多少張桌子。然而一張桌子上面只能坐上相互熟悉的人,其中熟悉可定義成為a與b認識,b與c認識,我們就說a,b,c相互熟悉 例如a與b熟悉and b與c熟悉,d與e熟悉,此時至少需要兩張桌子。輸入 t表示樣例個數,n表示朋友個數,朋友從1到n編號...