jzoj1500 秤

Description

秤是由秤桿、繩、和物品組成,每個秤桿被一根連着中點處的繩子掛着,杆子的兩端也都掛着一根繩子,下面可以直接掛物品,也可以掛另一個秤桿,秤桿可以任意旋轉。
現在給你兩把秤,要求判斷這兩把秤是否一樣。秤的表示方法如下,假設秤一共有N個秤桿,用1到N來編號,1號秤桿總是最上面的那個秤桿,每個秤桿兩邊懸掛物品或者是另一個秤桿,物品用一個負數或0來表示物品的種類(-9999..0),而用正數表示懸掛的秤桿的編號。

Input

輸入包含兩把秤的描述,秤的描述方法如下:第一行輸入一個整數N(1<=N<=100,000)表示秤中秤桿的數量,接下來N行,每行兩個整數,表示第i個秤桿兩邊懸掛的情況。

Output

如果兩把秤不同輸出“Fred and Mary have different mobiles.”,否則輸出“Fred and Mary might have the same mobile.”。

Sample Input&Sample output

5
2 3
4 5
-1 -2
-3 -4
-5 -6
5
2 5
-1 -2
-3 -4
-5 -6
3 4

Fred and Mary might have the same mobile.

5
2 3
4 5
-3 -4
-1 -2
-5 -6
5
2 5
-1 -2
-3 -4
-5 -6
3 4

Fred and Mary have different mobiles.

算法討論

可以看做判斷兩棵樹的每一個節點下放的東西是否相同。可用遞歸實現:
x,y分別爲兩棵樹的第x個節點和第y個節點,共有3中情況
(1)都爲物體,兩棵樹共4個,分爲兩種情況兩兩比較,滿足一種情況返回true,否則false
(2)一個物體和一個節點,滿足物體相同且遞歸兩個節點返回true才返回true
(3)都爲節點,與同1同理,兩兩遞歸,滿足其一即可

var
  a:array[-10000..0] of longint;
  x,y,xx,yy:array[1..110000] of longint;
  n,m,i:longint;
procedure dg(c,v:longint);
begin
  if c<0 then
    a[c]:=v
  else
    begin
      dg(x[c],v+1);
      dg(xx[c],v+1);
    end;
end;
procedure gd(c,v:longint);
begin
  if c<0 then
    begin
      if a[c]<>v then
        begin
          writeln('Fred and Mary have different mobiles.');
          halt;
        end;
    end
  else
    begin
      gd(y[c],v+1);
      gd(yy[c],v+1);
    end;
end;
begin
  readln(n);
  for i:=1 to n do
    readln(x[i],xx[i]);
  readln(m);
  for i:=1 to m do
    readln(y[i],yy[i]);
  dg(1,1);
  gd(1,1);
  writeln('Fred and Mary might have the same mobile');
end.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章