zoukankan      html  css  js  c++  java
  • 结题报告--P5551洛谷--Chino的树学

    题目:点此

                                 题目描述

    Chino树是一棵具有某种性质的满二叉树,具体来说,对于这棵树的每一个非叶子节点,它的左子节点(A)(A)(A)的右子节点(C)(C)(C)与它的右子节点(B)(B)(B)的左子节点(D)(D)(D)的值相同,且CCC与DDD下方的子树也完全相同。现在,Chino想知道,要如何从根节点走到其中任意叶节点使路上经过的节点的权值之和最大。

                                   思路

    先分析一下Chino树(满二叉树)的性质(节点编号)。

    k层的满二叉树的最后一个结点的编号是2k-1,第一个叶子结点的编号是2k-1,由此可知,判断节点是否为叶子:if(i>=pow(2,k-1)//i为结点编号                  判断此编号是否有对应节点:if(i>=0&&i<=pow(2,k)-1)//i为编号

    定义一个变量n_1存储2k-1,再定义一个变量x=n_1*2-1(就是2k-1)。

    本题难点之一就是把以深搜序列输入的树变成在数组里存储的树(数组存储是广搜序列),这个问题的解决方法是:在递归建树的函数里加一个参数now_number,表示现在是数组下标几了,因为数组下标是可以计算的:左子树下标:now_number*2,右子树下标:now_number*2+1。再加一个max_node_number,表示最大的结点编号,判断是否有左子树或右子树。

    接下来就是判断最大值了。使用先根遍历遍历二叉树,由于这棵树是用数组存储的,所以这篇博客里的in_oder函数的参数可以变为now_number,再加一个now_weight,表示现在的结点权值和。

    这个函数里执行:先更新now_weight,把此节点权值加进去。然后判断此节点是否为叶子,若是则判断是否为最大值,若是则更新最大值,结束,不是叶子则按照先根遍历的方法继续遍历。

    最后主函数就是这些函数的结合。

    (犯的错误和收获全部丢失,无法叙述)

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 using namespace std;
     4 int tree[17000000];
     5 int read()
     6 {
     7     int s=0,w=1;
     8     char ch=getchar();
     9     while(ch<'0'||ch>'9')
    10     {
    11         if(ch=='-')
    12             w=-1;
    13         ch=getchar();
    14     }
    15     while(ch>='0'&&ch<='9')
    16         s=s*10+ch-'0',ch=getchar();
    17     return s*w;
    18 }
    19 
    20 void maketree(int now_number,int max_node_number){
    21     int now_node;
    22     now_node=read();
    23     tree[now_number]=now_node;
    24     if(now_number*2>max_node_number){
    25         return ;
    26     }
    27     maketree(now_number*2,max_node_number);
    28     maketree(now_number*2+1,max_node_number);
    29 }
    30 int pow(int r){
    31     if(r==1){
    32         return 2;
    33     }
    34     int data=1;
    35     if(r%2==1){
    36         data=2;
    37     }
    38     int index=pow(r/2);
    39     return index*index*data;
    40 }
    41 int maxx,n_1;
    42 void pre_oder(int now_weight,int now_number){
    43     now_weight+=tree[now_number];
    44     if(now_number>=n_1){
    45         if(now_weight>maxx){
    46             maxx=now_weight;
    47         }
    48         return ;
    49     }
    50     pre_oder(now_weight,now_number*2);
    51     pre_oder(now_weight,now_number*2+1);
    52 }
    53 int main(){
    54     int n;
    55     n=read();
    56     n_1=pow(n-1);
    57     int x=n_1*2-1;
    58     maketree(1,x);
    59     pre_oder(0,1);
    60     cout << maxx;
    61     return 0;
    62 }
    代码
  • 相关阅读:
    Java字节流Stream的使用,创建方法
    Java中字节流和字符流复制文件
    Java中的IO流,Input和Output的用法,字节流和字符流的区别
    Java中String的常用方法总结
    java中File类的常用方法总结
    Java中递归的优缺点,Java写一个递归遍历目录下面的所有文件包括子文件夹里边的文件。
    Mysql 5.5从零开始学阅读笔记
    RDS for MySQL有哪些限制
    mysql查看建表语句命令
    MYSQL查看当前正在使用的数据库命令
  • 原文地址:https://www.cnblogs.com/eason66-blog/p/P5551--luogu.html
Copyright © 2011-2022 走看看