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

UVa122

Trees on the level

层次遍历二叉树。

这道题方便的地方在于不需要构建二叉树,可以直接对输入数据排序然后输出。但是由于输入数据可能导致二叉树不完整(或者节点重复),所以需要对二叉树的完整性进行判断,也就是在对输入节点按照层次遍历的要求排序后,先判断是否存在重复节点,然后再判断从根到每个节点的路径上的节点是否都存在。

#include <iostream>
#include <algorithm>
#include <set>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

struct Node
{
	int value;
	string path;
	Node(const string &pair)
	{
		string::size_type pos = pair.find(',');
		value = stoi(pair.substr(1, pos - 1));
		path.assign(pair.substr(pos + 1, pair.length() - pos - 2));
	}
};

bool CheckCompleteness(vector<Node> &nodes)
{
	if (!nodes.front().path.empty()) {
		return false;
	}
	for (size_t i = 1; i < nodes.size(); i++)
	{
		if (nodes[i - 1].path == nodes[i].path) {
			return false;
		}
	}
	set<string> paths;
	for (size_t i = 1; i < nodes.size(); i++)
	{
		const string &path = nodes[i].path;
		for (size_t len = 1; len < path.length() - 1; len++)
		{
			if (paths.find(path.substr(0, len)) == paths.end()) {
				return false;
			}
		}
		paths.insert(path);
	}
	return true;
}

void traverse(const vector<Node> &nodes)
{
	cout << nodes.front().value;
	for (size_t i = 1; i < nodes.size(); i++)
	{
		cout << ' ' << nodes[i].value;
	}
	cout << endl;
}

int main()
{
	vector<Node> nodes;
	string line;
	while (cin >> line) {
		stringstream ss(line);
		string pairs;
		while (ss >> pairs) {
			if (pairs == "()") {
				sort(nodes.begin(), nodes.end(), [](const Node &n1, const Node &n2)
				{
					if (n1.path.length() == n2.path.length())
						return n1.path < n2.path;
					else
						return n1.path.length() < n2.path.length();
				});
				if (CheckCompleteness(nodes)) {
					traverse(nodes);
				}
				else {
					cout << "not complete" << endl;
				}
				nodes.clear();
			}
			else {
				nodes.emplace_back(pairs);
			}
		}
	}
	return 0;
}
/*
(11,LL) (7,LLL) (8,R)
(5,) (4,L) (13,RL) (2,LLR) (1,RRR) (4,RR) ()
(3,L) (4,R) ()
*/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值