uva839 Not so Mobile (重建二叉树)

题意:天平的平衡条件 Wl * Dl == Wr * Dr。 题目给出的是 二叉树天平, 平衡条件是所有天平都要平衡。 大天平的W 是小天平两边的W总和(很明显嘛~ 不行你就受力分析下啊)。


思路:好了, 这题就无法逃脱建树的命运了。 递归建树, 然后递归判断是否平衡。每次读入一行, 如果Wl == 0, 则递归建左子树, 如果Wr == 0, 则递归建右子树。  判断的时候, 如果Wl == 0, 则递归判断左子树, 并返回左子树(左天平)的w。 右边也一样。 然后 判断 Wl * Dl == Wr * Dr。


算法复杂度:建树o(N)+ 判断o(N)+delete结点o(N) == o(3N) , 故算法复杂度为o(N)。 N为结点数。


代码:

#include <cstdio>
#include <cstring>
using namespace std;

#define LINE_NUM 4

struct Node
{
	int Wl;
	int Dl;
	int Wr;
	int Dr;
	Node *left;
	Node *right;
};

bool ok;

Node *mkTree();
void rmTree(Node *&);
int judge(Node *);		// judge and get weight

int main()
{
	int cases;
	scanf("%d", &cases);
	for (int css = 1; css <= cases; css++){
		// init
		Node *root = NULL;
		ok = true;

		// make tree
		root = mkTree();

		// judge
		if (css != 1) {
			printf("\n");
		}
		judge(root);
		if (ok) {
			printf("YES\n");
		} else {
			printf("NO\n");
		}

		// remove node
		rmTree(root);
	}

	return 0;
}

Node *mkTree()
{
	Node *root = new Node;
	scanf("%d%d", &root->Wl, &root->Dl);
	scanf("%d%d", &root->Wr, &root->Dr);

	if (root->Wl == 0) {
		root->left = mkTree();
	} else {
		root->left = NULL;
	}

	if (root->Wr == 0) {
		root->right = mkTree();
	} else {
		root->right = NULL;
	}

	return root;
}

void rmTree(Node *&root)
{
	if (root == NULL) {
		return;
	} else {
		rmTree(root->left);
		rmTree(root->right);
		delete root;
		root = NULL;
	}
}

int judge(Node *cur)
{
	if (!ok) {
		return 0;
	}

	if (cur->Wl == 0) {
		cur->Wl = judge(cur->left);	
	}
	if (cur->Wr == 0) {
		cur->Wr = judge(cur->right);
	}

	if (cur->Wl * cur->Dl != cur->Wr * cur->Dr) {
		ok = false;
	}

	return (cur->Wl + cur->Wr);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值