给定一棵包含 N 个节点的完全二叉树,树上每个节点都有一个权值,按从上到下、从左到右的顺序依次是 A1,A2,⋅⋅⋅AN,如下图所示:
现在小明要把相同深度的节点的权值加在一起,他想知道哪个深度的节点权值之和最大?
如果有多个深度的权值和同为最大,请你输出其中最小的深度。
注:根的深度是 1。
输入格式
第一行包含一个整数 N。
第二行包含 N 个整数 A1,A2,⋅⋅⋅AN。
输出格式
输出一个整数代表答案。
数据范围
1≤N≤,
−≤Ai≤
输入样例:
7 1 6 5 4 3 2 1
输出样例:
2
完全二叉树的概念:
一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为 i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。
思路:
双指针,记录起始位置和当前层二叉树的中元素的个数,利用一层循环求出总和并比较即可,可以当成满二叉树处理(下一层的节点数是上一层的两倍),当所求的元素总数与题目给出的 n 相同时,跳出循环。
完整代码(C++):
#include#include #include #include using namespace std; const int N = 1e5 + 10; int a[N]; //res.first 记录总和, res.second 记录层数 pair res = {0, 0}; int main() { int n; cin >> n; for(int i = 1; i <= n; i++) scanf("%d", &a[i]); res = {a[1], 1}; // i, j为指针头和尾 depth为深度 step为步长(即每层元素的个数) int i, j, depth = 1, step = 1; for(i = 1; i <= n; i = j, depth++) { long long tmp = 0; for(j = i; j <= i + step - 1 && j <= n; j++) { tmp += a[j]; } //如果两层的和相同,输出最小层,因此所求的和要严格大于之前所求最大值 if(tmp > res.first) { res.first = tmp; res.second = depth; } step *= 2; } cout << res.second << endl; return 0; }



