双指针(模拟)-第十届蓝桥杯省赛C++A/B组-完全二叉树的权值

双指针(模拟)-第十届蓝桥杯省赛C++A/B组-完全二叉树的权值

题目:

给定一棵包含 N 个节点的完全二叉树,树上每个节点都有一个权值,按从上到下、从左到右的顺序依次是 A1,A2,⋅⋅⋅AN,如下图所示:
在这里插入图片描述
现在小明要把相同深度的节点的权值加在一起,他想知道哪个深度的节点权值之和最大?

如果有多个深度的权值和同为最大,请你输出其中最小的深度。

注:根的深度是 1。

输入格式
第一行包含一个整数 N。

第二行包含 N 个整数 A1,A2,⋅⋅⋅AN。

输出格式
输出一个整数代表答案。

数据范围
1≤N≤105,
−105≤Ai≤105
输入样例:
7
1 6 5 4 3 2 1
输出样例:
2

题意:

求一颗完全二叉树每一层的和的最大值所在的深度。

题解:

O(n)直接模拟对每一层的数求和同时更新最大值所在的深度即可,每个数只加一遍,时间复杂度O(n)。

2n2的n次幂可以借助移位运算符,不必写快速幂。


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define P pair<int,int>
#define x first
#define y second
#define ll long long
#define inf 0x7fffffff
using namespace std;
const int N=1e5+10;
int n;
int a[N];

int log_2(int x)
{
    int cnt=0;
    while(x)
    {
        x/=2;
        cnt++;
    }
    return cnt;
}

int main()
{
    cin>>n;
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);

    ll h,msum=-inf;
    for(int i=1;i<=log_2(n);i++)
    {
        ll tmp=0;
        for(int j=1<<i-1;j<min((ll)n+1,(ll)1<<i);j++)
            tmp+=a[j];

        if(tmp>msum)
        {
            msum=tmp;
            h=i;
        }
    }

    cout<<h<<endl;
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章