题目链接
https://vjudge.net/problem/UVA-699
题目大意
给一棵二叉树,每个结点都有一个水平位置:左子结点在它左边1个单位,右子结点在右边1个单位。从左向右输出每个水平位置的所有结点的权值之和。如图6-7所示,从左到右的3个位置的权和分别为7,11,3。按照递归(先序)方式输入,用-1表示空树。
解题思路
先序递归隐式建树,同时统计每一列的和。我们并不需要真的建树,在递归的过程中我们无需知道每个节点的具体编号,只需要知道当前节点列编号即可,为了方便实现,我们将整棵树的根节点视为0列,往左为-1列,往右为+1列,这样做列数会有负数,所以使用map来维护每一列的和。
代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
const int maxn = 1e3 + 10;
const int INF = 0x3fffffff;
const int mod = 1e9 + 7;
map<int, int> sum; // 记录每一列的和bool Cacl(int col) { // 隐式建树并统计每一列的和int x;cin >> x;if (x == -1)return false;sum[col] += x; // 维护每一列的和Cacl(col - 1); // 递归左子树Cacl(col + 1); // 递归右子树return true;
}void solve() {int Case = 0;while (Cacl(0)) {++Case;cout << "Case " << Case << ":\n";for (auto p = sum.begin(); p != sum.end(); p++) {if (p != sum.begin())cout << " ";cout << p->second;}cout << "\n\n";sum.clear(); // 一定不要忘记了每组数据结束后容器的清空初始化}
}int main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cout << fixed;cout.precision(18);solve();return 0;
}