题面
输入一个树状天平,根据力矩相等原则判断是否平衡。如图6-5所示,所谓力矩相等, 就是WlDl=WrDr,其中Wl和Wr分别为左右两边砝码的重量,D为距离。 采用递归(先序)方式输入:每个天平的格式为Wl,Dl,Wr,Dr,当Wl或Wr为0时,表 示该“砝码”实际是一个子天平,接下来会描述这个子天平。当Wl=Wr=0时,会先描述左子天 平,然后是右子天平。 样例输入: 10 2 0 4 0 3 0 1 1 1 1 1 2 4 4 2
1 6 3 2 其正确输出为YES,
思路
紫书里面二叉树章节的题目,个人觉得二叉树的建立和遍历等主要还是对于递归算法的理解。这道题也是一样,题目的代码十分精简,但我们应该仔细关注一下细节方面。首先我们一看到题目就会想到二叉树,但本题不同的是这个二叉树的边上是带权值的,我们要是老老实实建树遍历当然十分麻烦。我们递归的考虑问题,当我们访问一个节点的时候,判断这个时候当前这个子天平是否平衡应该怎么做?我们需要统计这个时候的左右距离和权值的乘积是否一样,并且如果前置条件左天平和右天平的平衡不成立的话,那么自然这个大天平也不会成立。在代码里面我们可以看到,递归下降的过程中,程序还开了一个引用来从下到上,还原天平重量。
代码实现
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
bool solve (int &w) {
int w1,d1,w2,d2;
bool b1=true,b2=true;
cin>>w1>>d1>>w2>>d2;
if (!w1) b1=solve (w1);
if (!w2) b2=solve (w2);
w=w1+w2;
return b1&&b2&&(w1*b1==w2*b2);
}
int main () {
int t,w;
cin>>t;
while (t--) {
if (solve (w)) cout<<"yes"<<endl;
else cout<<"no"<<endl;
if (t) cout<<"
";
}
return 0;
}