完全二叉树的权值

试题 F: 完全二叉树的权值

时间限制: 1.0s 内存限制: 256.0MB 本题总分:15 分

【问题描述】
给定一棵包含 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.数据结构:使用双重指针代替二维数组(题目为明确给出数据范围,使用 “ 边长数组 ” 动态分配空间)

2.

代码实现(C++版本)

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <malloc.h>
#include <string.h>

using namespace std;

int n;

int main()
{
    cin >> n;

    int count=0, deep=0;//变量均要进行初始化
    while (count < n)
    {
        deep++;
        count += pow(2.0, (deep - 1));
    }//计算出节点个数为n 的完全二叉树的深度

    int** tree=(int**)malloc((deep + 1) * sizeof(int *));

    for (int i = 0; i < deep+1; i++)
    {
        tree[i] = (int*)malloc((deep + 1) * sizeof(int*));
        memset(tree[i], 0, (deep + 1) * sizeof(int));
    }//对完全二叉树逐层分配空间,并初始化
    
    count = 0;

    int temp_sum=0, temp_max=0,res=0;
    for (int temp_deep = 0; temp_deep < deep; temp_deep++)
    {
        for (int i = 0; i < pow(2.0, temp_deep); i++)
        {
            cin >> tree[temp_deep][i];
            count++;
            if (count >= n)    break;//完全二叉树的最后一层可以不填满
        }
    }//对二叉树进行初始化,将值全部放入二叉树中

    int deep_max = 0, sum_max = 0;
    for (int temp_deep = 1; temp_deep <= deep; temp_deep++)
    {
        int sum = 0;
        for (int i = 1; i <= pow(2.0, (temp_deep-1)); i++)    sum += tree[temp_deep][i];

        if (sum > sum_max)
        {
            deep_max = temp_deep;
            deep_max = temp_deep;
        }
    }//逐层比较二叉树权值,并输出权值最高的那层

    cout << res << endl;

    return 0;
}

/*

源代码(C语言版本)

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include <iostream>//头文件结束

using namespace std;

int n;

int main()
{
    cin>> n;

    int count = 0, deep = 0;
    while (count < n)
    {
        deep++;
        count += pow(2.0, (deep - 1));
    }//计算节点总数为n的完全二叉树的深度

    int** tree;
    tree = (int**)malloc((deep + 1) * sizeof(int*));
    for (int i = 0; i < deep + 1; i++)
    {
        tree[i] = (int*)malloc((deep + 1) * sizeof(int));
        memset(tree[i], 0, (deep + 1) * sizeof(int));
    }//双指针+malloc存储完全二叉树,节点个数未知

    // 将输入的值让完全二叉树的规则输入数组
    count = 0;

    for (int temp_deep = 1; temp_deep <= deep; temp_deep++)
    {
        for (int i = 1; i <= pow(2.0, temp_deep - 1); i++)
        {
            scanf("%d", &tree[temp_deep][i]);
            count++;
            if (count >= n) break;  // 当所有元素写入之后推出输入循环
        }
    }

    // 比较同一深度的节点权值之和
    int max_deep = 0, max_sum = 0;

    for (int temp_deep = 1; temp_deep <= deep; temp_deep++)
    {
        int sum = 0;
        for (int i = 1; i <= pow(2.0, temp_deep - 1); i++)
        {
            sum += tree[temp_deep][i];
        }
        if (sum > max_sum)
        {
            max_sum = sum;
            max_deep = temp_deep;
        }
    }

    printf("深度为 %d 的节点权值之和最大\n", max_deep);

    printf("\n");
    system("pause");
}


Pow函数详解:
 头文件:#include <math.h>

pow() 函数用来求 x 的 y 次幂(次方),x、y及函数值都是double型 ,其原型为:
    double pow(double x, double y);

pow()用来计算以x 为底的 y 次方值,然后将结果返回。设返回值为 ret,则 ret = x y 。

可能导致错误的情况:

    如果底数 x 为负数并且指数 y 不是整数,将会导致 domain error 错误。
    如果底数 x 和指数 y 都是 0,可能会导致 domain error 错误,也可能没有;这跟库的实现有关。
    如果底数 x 是 0,指数 y 是负数,可能会导致 domain error 或 pole error 错误,也可能没有;这跟库的实现有关。
    如果返回值 ret 太大或者太小,将会导致 range error 错误。


错误代码:

    如果发生 domain error 错误,那么全局变量 errno 将被设置为  EDOM;
    如果发生 pole error 或 range error 错误,那么全局变量 errno 将被设置为 ERANGE。

Math.pow(底数,几次方)
如:double a=2.0;
    double b=3.0;
double c=Math.pow(a,b);
就是2的三次方是多少;
c最终为8.0;
*/

原文地址:https://www.cnblogs.com/WAsbry/p/13916500.html