P8681 [藍橋杯 2019 省 AB] 完全二叉樹的權值

心悟&&星际發表於2024-03-14

題目描述

給定一棵包含N 個節點的完全二叉樹,樹上每個節點都有一個權值,按從上到下、從左到右的順序依次是​,如下圖所示:

現在小明要把相同深度的節點的權值加在一起,他想知道哪個深度的節點權值之和最大?如果有多個深度的權值和同為最大,請你輸出其中最小的深度。

注:根的深度是 1。

輸入格式

第一行包含一個整數 N。

第二行包含N 個整數 ​。

輸出格式

輸出一個整數代表答案。

輸入輸出樣例

輸入 #1複製

7

1 6 5 4 3 2 1

輸出 #1複製

2

說明/提示

對於所有評測用例,。

藍橋杯 2019 省賽 A 組 F 題(B 組 G 題)。

題意分析

由完全二叉樹的陣列儲存可知,第一層的元素個數為1個元素,第二層的元素個數為2,第i層的元素為2i 個,故問題轉化為分別統計各層元素的和,同時比較其最大值在第幾層,如果最大值相同求層數最小的哪個層數是多少。

程式碼一

#include<iostream>
#include<cmath>
using namespace std;
int main()
{
         long long ans=-10e10,cur=0;//是到當前位置時的最大值為ans,cur為當前層所有元素之和,注意cur,ans的取值範圍。
         int n,b,c=1,sd=1,l=2;//sd為最大值所在的層數,l表示當前是第幾層
         b=c=2;//當c計算第i層有幾個元素,b表示當前層已統計了幾個元素。
         cin>>n;
         cin>>ans;
         for (int i=2;i<=n;i++)
         {
                  int x;
                  cin>>x;
                  cur+=x;
                  b--;
                  if (b==0||i==n)
                  {
                          if (ans<cur)
                          {
                                   ans=cur;
                                   sd=l;        
                          }
                          l++;
                          c*=2;
                          b=c;
                          cur=0;
                  }
         }
         cout<<sd<<endl;
}

 

程式碼二,樹的遍歷法

#include<iostream>
using namespace std;
const int maxn=1e5+10;
int a[maxn],n,dep;
long long b[100];
void dfs(int x,int d)//x當前結點編號,d當前結點的深度。
{
         if (x>n) return ;
         dep=max(dep,d);//樹的深度
         b[d]+=a[x];//同一層的元素的和
         dfs(2*x,d+1);
         dfs(2*x+1,d+1);
}
int main()
{
         cin>>n;
         for (int i=1;i<=n;i++)
         {
                  cin>>a[i];
         }
         dfs(1,1);
         int ansi=1;
         for (int i=1;i<=dep;i++)//查詢第一個最大值的位置,思考與dfs是否可以合併
         {
                  if (b[ansi]<b[i]) ansi=i;
         }
         cout<<ansi<<endl;
}

  合併一下

#include<iostream>
using namespace std;
const int maxn=1e5+10;
int a[maxn],n,ansi=1;
long long b[100];
void dfs(int x,int d)
{
      if (x>n) return ;
      b[d]+=a[x];
      dfs(2*x,d+1);
      dfs(2*x+1,d+1);
      if (b[ansi]<b[d]) ansi=d;
}
int main()
{
      cin>>n;
      for (int i=1;i<=n;i++)
      {
             cin>>a[i];
      }
      dfs(1,1);
      cout<<ansi<<endl;
}

  

相關文章