ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

蓝桥杯【真题演练】完全二叉树的权值

2022-02-10 13:01:58  阅读:162  来源: 互联网

标签:真题 int 深度 pos long 蓝桥 二叉树 权值


【问题描述】

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

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

       注:根的深度是 1。

【输入格式】

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

【输出格式】

       输出一个整数代表答案。

【样例输入】

7
1 6 5 4 3 2 1

【样例输出】

2

【评测用例规模与约定】

       对于所有评测用例,1≤ N ≤100000,−100000≤ Ai ≤100000。

思路1

本题重点考察的是二叉树的有关性质,和存储结构二叉树关系不大。

 由上图分析可知,当层数为j时,每层元素在数组中的地址在区间 [  2^(j-1) , 2^j ) 中,这是核心点

然后将每层元素进行求和比较,即可得到权值之和最大所在的层数。因为是从第1层开始由下而上计算,所以之后某一层出现了和当前层权值之和相同时,无需更新层数,此时当前层就是深度最小的。

代码1

代码中用到<cmath>中的相关函数,常用函数小结如下:

函数名称函数说明
floor (x)向下取整,即不大于x的最大整数
ceil(x)向上取整,即不小于x的最小整数
pow(x,y)幂函数,即计算x的y次幂
sqrt(x)开平方函数,即求x的平方根
round(x)四舍五入函数,即四舍五入x得到离它最近的整数
log(x)对数函数,即求以e为底x的对数,常用换底公式进行对数计算
#include<iostream>
#include<cmath>
using namespace std;
const int N = 100005;
long long a[N]={0};
int main(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];//下标从1开始与完全二叉树的序号一致,便于操作 
	} 
	long max=0,sum=0;
	int i,j,depth=0;
	for(i=1;i<=floor(log(n)/log(2))+1;i++){//floor()为向下取整函数 
		sum=0;
		for(j=pow(2,i-1);j<pow(2,i);j++){
			sum+=a[j];
			if(j==n)break;//说明已经操作到最后一个结点,先跳出内循环 
		}
		if(sum>max){
			max=sum;
			depth=i;
		}
		if(j==n)break;//接着跳出外循环,计算结束 
	}
	cout<<depth;
	return 0;
}

思路2

思路1中是利用深度来求得各层元素在数组中地址的范围,然后累加求和比较

思路2则是采用在数组中设置“移动”变量pos,移动的距离为每层的元素个数

要注意的是要判断是否为满二叉树,因为题目中的图具有一定的迷惑性,完全二叉树不一定是满二叉树,所以要对最后一层的元素个数与那一层至多有多少元素进行比较,相等则为满二叉树,小于则是非满二叉树。

代码2

#include<iostream>
#include<cmath>
using namespace std;
const int N = 100005;
long long a[N]={0};
int main(){
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>a[i];
	} 
	int deep=1,pos=0;
	long long max=0;
	int depth=floor(log(n)/log(2))+1;//含有n个结点的完全二叉树的深度 
	for(int i=1;i<=depth;i++){
		long long sum=0;
		int node=pow(2,i-1);//第i层最多的结点数 
		//非满二叉树 
		int temp=n-pos;//必须要先保存n-pos的值,因为pos是不断移动变化的 
		if(temp<node){
			for(int j=0;j<temp;j++){
				sum+=a[pos++];
			}
		} 
		//满二叉树 
		else{
			for(int j=0;j<node;j++){
				sum+=a[pos++];
			}
		}
		if(sum>max){
			max=sum;
			deep=i;
		}
	}
	cout<<deep<<endl;
	return 0;
}

总结

思路2的做法,在进行非满二叉树相关操作时,我一开始的代码有个细节错误,就是没有保存n-pos的值然后直接进行下面操作了,因为pos是不断移动变化的,所以n-pos也是变化的,而我们所要的是一开始操作时的n-pos值进行非满二叉树的判定。这也是10个测试点硬是有一个一直不通过的原因!

错误代码:

 正确代码:

 可能发现后现在觉得这就是一个考虑不周全的小问题,但是自己找了半天,结果让朋友帮我看,五分钟就找到原因了,真所谓“ 当局者迷,旁观者清 ”,所以以后在一些小细节的处理上一定一定要更加严谨!要快,但更要准。

标签:真题,int,深度,pos,long,蓝桥,二叉树,权值
来源: https://blog.csdn.net/qq_52487066/article/details/122837437

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有