题目描述
输入一个树状天平,根据力矩相等原则判断是否平衡。如图所示,所谓力矩相等就是WlDl=Wr Dr,其中Wl和Wr分别为左右两边砝码的重量,D为距离。
输入格式
输入的第一行,是一个整数n,表示测试数据的组数。紧接着是一个空行。每组测试数据之间也有一个空行。
每组测试数据,包含多行,采用递归(先序)方式输入,每行用空格隔开的4个整数,分别代表Wl、Dl、Wr、Dr。当Wl或Wr为0时,表示该"砝码"实际是一个子天平,接下来会描述这个子天平。当Wl=Wr=0时,会先描述左子天平,然后是右子天平。
例如:输入样例就描述了下图的天平:
输出格式
对于每组测试数据,输出一行,如果天平平衡输出'YES',否则输出'NO'。两组测试数据结果之间输出一个空行。
输入输出样例
输入样例1:
1
0 2 0 4
0 3 0 1
1 1 1 1
2 4 4 2
1 6 3 2
输出样例1:
YES
说明
数据保证"天平"总数不超过400
【耗时限制】3000ms 【内存限制】128MB
cpp
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct st{
ll wl,dl,wr,dr;
ll l,r;
}a[500];
ll n,tot,cntw[500];
ll build(){
ll r=++tot;
scanf("%lld%lld%lld%lld",&a[r].wl,&a[r].dl,&a[r].wr,&a[r].dr);
if(!a[r].wl)a[r].l=build();
if(!a[r].wr)a[r].r=build();
return r;
}
ll count(ll r){
if(!r)return 0;
cntw[r]=count(a[r].l)+count(a[r].r)+a[r].wl+a[r].wr;
return cntw[r];
}
int main(){
scanf("%lld",&n);
while(n--){
memset(a,0,sizeof a);
tot=0;
ll r=build();
count(r);
ll ok=1;
for(ll r=1;r<=tot;r++){
ll wl,wr;
if(!a[r].wl)wl=cntw[a[r].l];
else wl=a[r].wl;
if(!a[r].wr)wr=cntw[a[r].r];
else wr=a[r].wr;
if(wl*a[r].dl!=wr*a[r].dr){
ok=0;
break;
}
}
if(ok)printf("YES\n\n");
else printf("NO\n\n");
}
return 0;
}