• Dropping Balls(小球下落)


    紫书P148,例题6-6

     

    Sample Input 

    4 2
    3 4
    10 1
    2 2
    8 128
    

    Sample Output 

    12
    7
    512
    3
    255

    这应该不仅仅是一棵完全二叉树,题目中说保证所有叶子节点的深度都相同,所以这是一颗满二叉树。

    这里要弄清满二叉树的一些概念和性质,首先,对于一颗满二叉树来说,他每一层的节点数都达到最大,那么对于一个K层的满二叉树来说,他的节点数有(2^k)-1个

    而且研究满二叉树和完全二叉树的一个好处在于他可以实现顺序存储,如图中的可以表示为

    值   :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

    位置:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

    其中i节点的左孩子为2*i,右孩子为2*i+1

    掌握了这一点,即使给出的树的值不是严格的从上到下,从左至有右的递增序列,也能很轻松的搞定了

    #include <iostream>
    #include <cstdio>
    using namespace std;
    int a[(1<<20)+10];
    int main()
    {
        int D,N;
        while(~scanf("%d%d",&D,&N))
        {
            int m=(1<<D)-1;
            for(int i=1;i<=m;i++) {a[i]=0;}
            int p;
            for(int i=1;i<=N;i++)
            {
                p=1;
                while(1)
                {
                    if(a[p]==0)
                        {a[p]=1;p=p*2;}
                    else
                        {a[p]=0;p=p*2+1;}
                    if(p>(1<<(D-1))-1) break;
                }
            }
            cout<<p<<endl;
        }
        return 0;
    }
    View Code

     可是单单这样进行模拟,时间上太过浪费:

    可以直接进行分析,如果一个根节点被访问了5次,那么他的左孩子节点必定被访问了3次,右孩子必定被访问了2次,我们是怎么得出这个结论的呢?

    显然当处在某个节点上的球不是往左走就是往右,而且最初是往左的,那么左边必被分到((n+1)/2)次,右边分到(n/2)次

    推而广之可得对于n这个小球到达每个点时应该向左还是向右

    #include <iostream>
    using namespace std;
    int main()
    {
        int D,N;
        while(cin>>D>>N)
        {
         int p=1;
         for(int i=1;i<D;i++)
         {
            if(N%2)
            {
                p=p*2;           
                N=(N+1)/2; 
            }
            else
            {
                p=p*2+1;
                N=N/2;
            }
         }
         cout<<p<<endl;
        }
        return 0;
    }
    View Code

                                                                                                                          

  • 相关阅读:
    MySQL中IS NULL、IS NOT NULL、!=不能用索引?胡扯!
    市值TOP10,人类进化及中美坐标
    倒序切片
    对list进行切片
    Python之定义可变参数
    Python之递归函数
    Python之“可变”的tuple
    Python之创建单元素tuple
    Python中Unicode字符串
    Pycharm配置autopep8让Python代码更符合pep8规范
  • 原文地址:https://www.cnblogs.com/zsyacm666666/p/5000162.html
Copyright © 2020-2023  润新知