【洛谷 P8681】[蓝桥杯 2019 省 AB] 完全二叉树的权值 题解(完全二叉树+数学)

[蓝桥杯 2019 省 AB] 完全二叉树的权值

题目描述

给定一棵包含 N N N 个节点的完全二叉树,树上每个节点都有一个权值,按从上到下、从左到右的顺序依次是 A 1 , A 2 , ⋯ A N A_1,A_2, \cdots A_N A1,A2,AN,如下图所示:

现在小明要把相同深度的节点的权值加在一起,他想知道哪个深度的节点权值之和最大?如果有多个深度的权值和同为最大,请你输出其中最小的深度。

注:根的深度是 1 1 1

输入格式

第一行包含一个整数 N N N

第二行包含 N N N 个整数 A 1 , A 2 , ⋯   , A N A_1,A_2, \cdots, A_N A1,A2,,AN

输出格式

输出一个整数代表答案。

样例 #1

样例输入 #1

7
1 6 5 4 3 2 1

样例输出 #1

2

提示

对于所有评测用例, 1 ≤ N ≤ 1 0 5 1 \le N \le 10^5 1N105 0 ≤ ∣ A i ∣ ≤ 1 0 5 0 \le |A_i| \le 10^5 0Ai105

蓝桥杯 2019 省赛 A 组 F 题(B 组 G 题)。


思路

利用完全二叉树的性质:完全二叉树的每一层(除了可能的最后一层)都是完全填充的。这意味着在深度 d d d处,节点的数量最多是 2 d − 1 2^{d-1} 2d1

首先,读取完全二叉树的节点数 n n n。定义几个变量,包括当前深度 d d d、当前层的权值之和 s u m sum sum、最大权值之和 w m a x wmax wmax以及对应的最大深度 d m a x dmax dmax

接着,开始遍历完全二叉树的每一层。每一层的节点数是 2 d − 1 2^{d-1} 2d1,其中 d d d是当前深度。然后,读取每个节点的权值,累加到当前层的权值之和 s u m sum sum中。

在遍历完一层后,比较当前层的权值之和 s u m sum sum与最大权值之和 w m a x wmax wmax,如果 s u m sum sum更大,则更新最大权值之和 w m a x wmax wmax和对应的最大深度 d m a x dmax dmax

最后,将最大深度 d m a x dmax dmax输出。

注意

完全二叉树不一定是满二叉树,最后一层不一定是完全填充的。所以最后一层的节点的数量可能不是 2 d − 1 2^{d-1} 2d1。当所有节点已经读取完毕后,应该停止输入,否则无法通过部分测试点。


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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值