算法竞赛入门经典 例题6-9

UVa839

Not so Mobile

判断树形的杠杆是否平衡。

根据题目要求构建二叉树判断平衡即可。

#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

struct Lever
{
	int W_l, D_l, W_r, D_r;
};

struct Node
{
	int weight, D_l, D_r;
	shared_ptr<Node> left, right;
};

class Solution
{
public:
	Solution(istream &is)
	{
		string line;
		while (getline(is, line)) {
			if (line.empty()) break;
			levers.push_back(Lever());
			stringstream ss(line);
			ss >> levers.back().W_l >> levers.back().D_l >> levers.back().W_r >> levers.back().D_r;
		}
		size_t index = 0;
		construct(tree, index);
	}
	bool equilibrium = true;
private:
	vector<Lever> levers;
	Node tree;
	void construct(Node &root, size_t &index)
	{
		const Lever &lever = levers.at(index++);
		root.D_l = lever.D_l, root.D_r = lever.D_r;
		if (lever.W_l == 0 && lever.W_r == 0) {
			root.left = make_shared<Node>();
			construct(*root.left, index);
			root.right = make_shared<Node>();
			construct(*root.right, index);
			root.weight = root.left->weight + root.right->weight;
			equilibrium &= root.left->weight * lever.D_l == root.right->weight * lever.D_r;
		}
		else if (lever.W_l != 0 && lever.W_r != 0) {
			root.weight = lever.W_l + lever.W_r;
			equilibrium &= lever.W_l * lever.D_l == lever.W_r * lever.D_r;
		}
		else if (lever.W_l != 0) {
			root.right = make_shared<Node>();
			construct(*root.right, index);
			root.weight = root.right->weight + lever.W_l;
			equilibrium &= lever.W_l * lever.D_l == root.right->weight * lever.D_r;
		}
		else {
			root.left = make_shared<Node>();
			construct(*root.left, index);
			root.weight = root.left->weight + lever.W_r;
			equilibrium &= root.left->weight * lever.D_l == lever.W_r * lever.D_r;
		}
	}
};

int main()
{
	int cases;
	cin >> cases;
	cin.get();
	cin.get();
	for (int c = 0; c < cases; c++)
	{
		if (c != 0) cout << endl;
		Solution solution(cin);
		if (solution.equilibrium) cout << "YES" << endl;
		else cout << "NO" << endl;
	}
	return 0;
}
/*
1

0 2 0 4
0 3 0 1
1 1 1 1
2 4 4 2
1 6 3 2
*/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值