题意:
给出一个大天平,大天平中还有许多小天平,求出所有的天平是否平衡;平衡条件为wldl = wrdr;
题目
Before being an ubiquous communications gadget, a mobile
was just a structure made of strings and wires suspending
colourfull things. This kind of mobile is usually found hanging
over cradles of small babies.
The figure illustrates a simple mobile. It is just a wire,
suspended by a string, with an object on each side. It can
also be seen as a kind of lever with the fulcrum on the point where the string ties the wire. From the
lever principle we know that to balance a simple mobile the product of the weight of the objects by
their distance to the fulcrum must be equal. That is Wl × Dl = Wr × Dr where Dl
is the left distance,
Dr is the right distance, Wl
is the left weight and Wr is the right weight.
In a more complex mobile the object may be replaced by a sub-mobile, as shown in the next figure.
In this case it is not so straightforward to check if the mobile is balanced so we need you to write a
program that, given a description of a mobile as input, checks whether the mobile is in equilibrium or
not.
Input
The input begins with a single positive integer on a line by itself indicating the number
of the cases following, each of them as described below. This line is followed by a blank
line, and there is also a blank line between two consecutive inputs.
The input is composed of several lines, each containing 4 integers separated by a single space.
The 4 integers represent the distances of each object to the fulcrum and their weights, in the format:
Wl Dl Wr Dr
If Wl or Wr is zero then there is a sub-mobile hanging from that end and the following lines define
the the sub-mobile. In this case we compute the weight of the sub-mobile as the sum of weights of
all its objects, disregarding the weight of the wires and strings. If both Wl and Wr are zero then the
following lines define two sub-mobiles: first the left then the right one.
Output
For each test case, the output must follow the description below. The outputs of two
consecutive cases will be separated by a blank line.
Write ‘YES’ if the mobile is in equilibrium, write ‘NO’ otherwise.
Sample Input
1
0 2 0 4
0 3 0 1
1 1 1 1
2 4 4 2
1 6 3 2
Sample Output
YES
方案一:思维:可以构造一个二叉树,递归求出每个子树是否平衡,传递判断天平是否平衡1,0;
错误出现:1,若在调用函数bfs中了.l,r定义为全局变量(且在调用中对r,l赋值),则错误。
因为赋值时会覆盖掉上一次获取的r,l的值。
解决方案1,将其定义为局部变量,每一次调用,r,l不为同一值,利用递归,对r,l的值进行传递。
2,定义全局变量,但在主函数中赋初值,用递归传递值
(2) 参数传递的方式是引用传递
对形参的任何操作都能改变相应的数据
#include<iostream>
#include<string.h>
using namespace std;
int t;
int bfs(int &p)//p 相当于此分支目前的重量
{/*递归传递判断天平是否平衡1,0*/int a,u,b,v;cin>>a>>u>>b>>v;///输入数据的时候正好可以构建树,当输入数完成后就构建成了一颗完整的树int l=1,r=1;/**care 可能l和r最后也没能赋值,为了到达叶节点可以比较,故赋初值*/if(a==0)l=bfs(a);/**判断左子树上,叶节点是否平衡*/if(b==0)r=bfs(b);/**判断右子树上,叶节点是否平衡*/p=a+b;///当输入结束,回溯过程时,左右子树重量相加,获得判断节点的重量和if(l&&r&&(a*u==b*v)) return 1;///左边,右边子树重量相等,再比较此时它的重量else return 0;
}
int main()
{cin>>t;while(t--){int x;int flag=bfs(x);///x 相当于此分支目前的重量if(flag) cout<<"YES"<<endl;else cout<<"NO"<<endl;if(t)cout<<endl;}return 0;
}
/**
在C++中,参数传递的方式是“实虚结合”。
A按值传递(pass by value) int x
B地址传递(pass by pointer) int *x
C引用传递(pass by reference) int &x
A调用函数本身不对实参进行操作,也就是说,即使形参的值在函数中发生了变化,实参的值也完全不会受
到影响,仍为调用前的值。
B地址传递与按值传递的不同在于,它把实参的存储地址传送给对应的形参,从而使得形参指针和实参指针
指向同一个地址。因此,被调用函数中对形参指针所指向的地址中内容的任何改变都会影响到实参。
C如果以引用为参数,可以使得对形参的任何操作都能改变相应的数据,引用传递方式是在函数定义时在形参前面加上引用运算符“&”。
*/
方案二
可以构造一个二叉树,递归求出每个子树是否平衡,并返回wl+wr作为父亲节点的w;
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int t,flag;
int dfs()
{int a=0,u,b=0,v;scanf("%d%d%d%d",&a,&u,&b,&v);if(a==0)a=dfs();if(b==0)b=dfs();if(a*u!=b*v)flag=1;return a+b;
}
int main()
{scanf("%d",&t);while(t--){flag=0;dfs();if(!flag)printf("YES\n");elseprintf("NO\n");if(t)printf("\n");}return 0;
}