Not so Mobile UVA

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;
}

好的思路代码就会很简洁。

原文地址:https://www.cnblogs.com/worldcreator-zh/p/10568761.html