https://vjudge.net/problem/UVA-839
最近看过的一道例题,感觉很有意思,再自己做一次。
给一个天平,给出天平左右两个力臂的长度和左右重物的重量,若给出的重量是0则意味着该侧有一个子天平,该侧重量是子天平的两侧重量之和。判断该天平是否平衡。
输入:
先给一个正整数n表示有n组输入。
接着每行四个数分别为天平的左重量,左力臂,右重量,右力臂。若有0,则下一行继续输入子天平,若左右都有子天平,则先输入左边的子天平,再右边。
输出:
输出该天平的是否平衡,YES或NO每行一个代表第n个天平,每组中间要空一行隔开(最后一行不要多打回车)。
一个二叉树的题,这个结构简直太符合二叉树了,而且输入的格式也是二叉树,可以看作是先序遍历整个树:
输入本节点->左结点->右结点 这样完全符合先序遍历。
这是一个递归,所以考虑下面几点
①:若天平平衡则所有子天平都应该平衡。所以每个结点都应该有一次w1*l1==w*l2的判断。且非叶子结点应该再将该天平状态&&上所有其子结点天平的状态。
②:若天平存在左子天平则w1的值应该为子天平w1*+w2*的和,右边也一样,若为一般情况即是没有子天平的叶子结点 则可以可以直接进行判断w1*l1==w*l2,并且
要将w1+w2的值返回给上一层的w1(或w2),所以要能在下一层递归中更改上一层的值,所以用引用的方式将上一层的(w1或w2)传参。(感觉真是绝了!!!)
③:进行递归的条件 就和先序一样,先进行输入,检测w1为0后,进行左子树遍历,然后在检测右子树,进行右子树遍历。
ac代码
#include<iostream> using namespace std; bool judge(int &w, bool& flag) { int w1, w2, l1, l2; cin >> w1 >> l1 >> w2 >> l2; if (!w1) flag=judge(w1, flag); if (!w2) flag=judge(w2, flag); w = w1 + w2; return (w1 * l1 == w2 * l2)&&flag; } int main() { int n; cin >> n; for (int i = 0; i < n; i++) { int w = 0; bool flag = true; if (judge(w, flag)) cout << "YES"; else cout << "NO"; cout << endl;if (i != n - 1) cout << endl; } return 0; }
好的思路代码就会很简洁。