[蓝桥杯 2019 省 AB] 完全二叉树的权值
题目描述
给定一棵包含 NNN 个节点的完全二叉树,树上每个节点都有一个权值,按从上到下、从左到右的顺序依次是 A1,A2,⋯ANA_1,A_2, \cdots A_NA1,A2,⋯AN,如下图所示:

现在小明要把相同深度的节点的权值加在一起,他想知道哪个深度的节点权值之和最大?如果有多个深度的权值和同为最大,请你输出其中最小的深度。
注:根的深度是 111。
输入格式
第一行包含一个整数 NNN。
第二行包含 NNN 个整数 A1,A2,⋯ ,ANA_1,A_2, \cdots, A_NA1,A2,⋯,AN。
输出格式
输出一个整数代表答案。
样例 #1
样例输入 #1
7
1 6 5 4 3 2 1
样例输出 #1
2
提示
对于所有评测用例,1≤N≤1051 \le N \le 10^51≤N≤105,0≤∣Ai∣≤1050 \le |A_i| \le 10^50≤∣Ai∣≤105。
蓝桥杯 2019 省赛 A 组 F 题(B 组 G 题)。
思路
利用完全二叉树的性质:完全二叉树的每一层(除了可能的最后一层)都是完全填充的。这意味着在深度ddd处,节点的数量最多是2d−12^{d-1}2d−1。
首先,读取完全二叉树的节点数nnn。定义几个变量,包括当前深度ddd、当前层的权值之和sumsumsum、最大权值之和wmaxwmaxwmax以及对应的最大深度dmaxdmaxdmax。
接着,开始遍历完全二叉树的每一层。每一层的节点数是2d−12^{d-1}2d−1,其中ddd是当前深度。然后,读取每个节点的权值,累加到当前层的权值之和sumsumsum中。
在遍历完一层后,比较当前层的权值之和sumsumsum与最大权值之和wmaxwmaxwmax,如果sumsumsum更大,则更新最大权值之和wmaxwmaxwmax和对应的最大深度dmaxdmaxdmax。
最后,将最大深度dmaxdmaxdmax输出。
注意
完全二叉树不一定是满二叉树,最后一层不一定是完全填充的。所以最后一层的节点的数量可能不是2d−12^{d-1}2d−1。当所有节点已经读取完毕后,应该停止输入,否则无法通过部分测试点。
AC代码
#include <algorithm>
#include <cmath>
#include <iostream>
#define AUTHOR "HEX9CF"
using namespace std;
using ll = long long;
const int N = 1e6 + 7;
const int INF = 0x3f3f3f3f;
const ll MOD = 1e9 + 7;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n;
cin >> n;
int d = 1;
ll wmax = 0;
int dmax = 0;
for (int i = 1; i <= n;) {
ll sum = 0;
for (int j = 1; j <= pow(2, d - 1) && i <= n; j++) {
int a;
cin >> a;
sum += a;
i++;
}
// cout << sum << "\n";
if (sum > wmax) {
wmax = sum;
dmax = d;
}
d++;
}
cout << dmax << "\n";
return 0;
}
分析了给定完全二叉树中相同深度节点权值求和的问题,展示了如何利用完全二叉树性质和层次遍历来找到最大权值和对应的最小深度。
678

被折叠的 条评论
为什么被折叠?



