最轻的天平 (Standard IO)

题意/Description:

       天平的两边有时不一定只能挂物品,还可以继续挂着另一个天平,现在给你一些天平的情况和他们之间的连接关系,要求使得所有天平都能平衡所需物品的总重量最轻,一个天平平衡当且仅当“左端点的重量*左端点到支点的距离=右端点的重量*右端点到支点的距离”。注意题目中的输入保证这些天平构成一个整体。

 

读入/Input

       第一行包含一个N(N<=100),表示天平的数量,,天平编号为1到N,接下来包含N行描述天平的情况,每行4个整数P,Q,R,B,P和Q表示横杆上支点到左边的长度与到右边的距离的比例为P:Q,R表示左边悬挂的情况,如果R=0说明悬挂的物品,否则表示左边悬挂的是天平R;B表示右边的悬挂情况,如果B=0表示右边悬挂的是物品,否则右边悬挂着天平B。
       对于所有的输入,保证W*L<2^31,   其中W为最请的天平重量,而L为输入中描述左右比例时出现的最大值。

 

输出/Output

        输出一个整数表示使得所有天平都平衡所需最轻的物品总重量。

 

题解/solution

       要想一个天平平衡,首先要使得左右天平两边平衡。假设左右两边的最轻重量 分别为W1,W2,设该天平左右两边的比例为L1:L2,要想使得该天平衡,可能左边要放大倍数  X,右边要放大倍数Y,则有以下关系式: W1*X*L1=W2*L2*Y; 

       即X/Y=(W2*L2)/(W1*L1),要想使天平重量最小,必须把X/Y化为最简分数,所以需要求出  W2*L2和W1*L1的最大公约数P,则X=W2*L2 div P ,Y=W1*L1 div P,整个天平的重量为 W1*X+W2*Y。

 

代码/Code

 

var
  i,kk,n:longint;
  o,p,l,r:array [0..101] of longint;
function gcd(x,y:longint):longint;
begin
  if y=0 then gcd:=x
         else gcd:=gcd(y,x mod y);
end;

function main(x:longint):longint;
var
  gc,lt,rt:int64;
begin
  if x=0 then exit(1) else
    begin
      lt:=main(l[x]);
      rt:=main(r[x]);
      gc:=gcd(rt*p[x],lt*o[x]);
      exit(lt*(rt*p[x] div gc)+rt*(o[x]*lt div gc));
    end;
end;

procedure init;
var
  i:longint;
  f:array [0..101] of boolean;
begin
  fillchar(f,sizeof(f),false);
  readln(n);
  for i:=1 to n do
    begin
      readln(o[i],p[i],l[i],r[i]);
      if l[i]<>0 then f[l[i]]:=true;
      if r[i]<>0 then f[r[i]]:=true;
    end;
  for i:=1 to n do
    if not f[i] then
      begin
        kk:=i;
        break;
      end;
end;

begin
  init;
  write(main(kk));
end.
posted @ 2016-07-20 16:07  猪都哭了  阅读(352)  评论(0编辑  收藏  举报