天平 UVa 839

高能预警:此文作者水平极差,漏洞百出,错误俯拾皆是,行文毫无逻辑!此文仅供作者自己研究所用。

不得不承认,刘汝佳老师实在是太厉害了(或许是因为我太弱鸡了、、、)

个人认为,最好理解这段代码的方式是这样:以题目给出的样例输入和图为例。递归函数有这样的性质:子函数没有结束之前,母函数是不会结束的。借用刘汝佳老师在紫书(P.77)中举得例子:知府还不知道今年收了多少粮食,皇帝怎么可能知道?也就是说,母函数中代码会有一部分只到子函数代码执行完毕后才执行,那么分界线在哪儿呢?就在第8行和第9行之间。我们可以按照题目中给出的样例不停地去制造子天平,只到真正给出一个个砝码的时候,当砝码被一个个给出,再去运行每个函数中的第9和第10行代码。(有点拗口,水平实在有限,求原谅,如果不原谅,请看本文开头的高能预警)正因为如此,主函数中声明的w有没有赋值是无所谓的,因为它总会被后来的值修改、覆盖。

另外,先序遍历的运算顺序是先沿左侧连进行,然后把左侧连末端的兄弟(也就是左侧连末端的父亲的右孩子)推进栈中,然后运行,参见邓俊辉老师的数据结构:http://www.xuetangx.com/courses/course-v1:TsinghuaX+30240184+sp/courseware/16d8402a24fd4429a8a7cc1c8401cb1f/ee9506a84ba64005a06aa6dc4773f27b/

另外,不妨温习一下刘老师给出的唯一注释:输入一个子天平,返回天平是否平衡,参数w修改为子天平的重量。

输入的是四个整数,返回的是布尔值,还修改了一个整数,amazing


#include<iostream>
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 + d1 == w2 + d2);
}

int main() {
    int t,w;
    cin >> t;
    while(t--) {
        if(solve(w)) cout << "YES\n"; else cout << "NO\n";
        if(t) cout << "\n";
    }
    return 0;
}

以下是没用的废话:

另外,个人认为,能把这个题和二叉树的先序遍历联系到一起也很不容易,个人的体会如下:

1、透过一些共有的、关键词汇,比如sub-mobile子天平,联系到二叉树中的左右孩子

2、数据结构是算法中很重要的一部分,所以对于题目,除了重视它的数据之外,还要看到它的结构

3、要学会去掉其复杂的背景,抽象出本质

4、利用所给的图,不妨把图重新画一下。

问题分解:

1、输入:可以以stringstream的形式来保存之。可是如何把递归给出的(先序遍历序列)给还原成一棵二叉树呢?(根本不需要建树,在输入的过程中就直接判断了,太厉害了!)

2、处理:就是判断它是否平衡呗

3、输出:设置一个全局变量

根节点的值可以用来判断是否平衡

难点:如何建树?以何种方式建树?

如果你只知道要用递归,但是不知道如何架构起递归,那么就强行在函数中重新用这个函数。这也是一种不得已而为之的方法。


猜你喜欢

转载自blog.csdn.net/huangming1644/article/details/79381962