例题6-10 UVA699 The Falling Leaves(23行AC代码)

紫书刷题进行中,题解系列【GitHub|CSDN

例题6-10 UVA699 The Falling Leaves(23行AC代码)

题目大意

以树根节点为中心,画一根垂直线(可看成y轴),因此树根坐标为0,它的左子树根为-1,右子树根为+1,依次类推,即往左走-1,往右走+1,现在将坐标相同的点看成一叠,从左到右输出他们的权值和。

思路分析

例题6-9有些类似,直观思路是想通过输入先序建树,然后再次dfs计算每叠的总和。

那么自然可利用同样的优化手段,即无需真正的建立一个二叉树,而是隐式建立二叉树(只遍历,不留下任何痕迹:),同时定义map<int,int> cnt;来统计每叠对应的权值总和,因为map对按键值从小到大排序,免去了输出时排序的繁琐,这也是为什么令左子树-1,右子树+1的缘故。

注意利用输入数据的先序特点,可使用递归建树,避免复杂的输入处理

注意点

  • 每组测试用例输出均需跟上一个空行!!!

AC代码(C++11,先序隐式建树,map)

#include<bits/stdc++.h>
using namespace std;
map<int,int> cnt; //  位置->个数;统计每叠对应权值总和
void createTree(int pos=0) { // 先序隐式建树,同时累加每个位置的值
    int v; scanf("%d", &v);
    if (v != -1) {
        cnt[pos] += v; // 累加值
        createTree(pos-1); // 左子树
        createTree(pos+1); // 右子树
    }
}
int main() {
    for (int i = 1; ; i ++) {
        cnt.clear(); createTree(0); // 初始化,隐式建树求值
        if (cnt.empty()) break; // 读到最后一个-1,结束
        printf("Case %d:\n", i);
        for (auto p : cnt) { // map按照key的字典序升序排列
            printf("%d%s", p.second, p.first == cnt.rbegin()->first ? "\n" : " ");
        }
        puts(""); // 每个测试用例后均有空行
    }
    return 0;
}
发布了128 篇原创文章 · 获赞 87 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_40738840/article/details/104318819