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;
}

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

可以直接进行分析,如果一个根节点被访问了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;
}

时间: 2024-10-30 14:08:40

Dropping Balls(小球下落)的相关文章

679 - Dropping Balls

Dropping Balls PS:因为该题排版较麻烦,这里给出OJ网址:UVa679 - Dropping Balls 有一棵二叉树,最大深度为D,且所有叶子的深度都相同.所有结点从上到下从左到右编号为1, 2, 3,-, 2D-1.在结点1处放一个小球,它会往下落.每个内结点上都有一个开关,初始全部关闭,当每次有小球落到一个开关上时,状态都会改变.当小球到达一个内结点时,如果该结点上的开关关闭,则往左走,否则往右走,直到走到叶子结点,如图6-2所示. 一些小球从结点1处依次开始下落,最后一个

UVA679 Dropping Balls【二叉树结点编号】

Dropping Balls A number of K balls are dropped one by one from the root of a fully binary tree structure FBT. Each time the ball being dropped first visits a non-terminal node. It then keeps moving down, either follows the path of the left subtree, o

[2016-02-08][UVA][679][Dropping Balls]

UVA - 679 Dropping Balls Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu Submit Status Description A number of K balls are dropped one by one from the root of a fully binary tree structure FBT. Each time the ball being dropped f

UVa679:Dropping Balls

Dropping Balls A number of K balls are dropped one by one from the root of a fully binary tree structure FBT. Each time the ball being dropped first visits a non-terminal node. It then keeps moving down, either follows the path of the left subtree, o

算法练习--小球下落

小球下落: 完全二叉树,最大深度D.所有节点从上到下从左到右编号为1,2,3...2的D次方-1.在节点1处放一个小球,它会往下落.每个内节点上都由一个开关,初始全部关闭,当每次有小球落到一个开关上时,它的状态都会改变.当小球达到一个内节点时,如果该节点上的开关关闭,往左走,否则往右走,直到遍历到叶子节点.问题,输入 深度和小球个数输出节点编号 输入 4 2  输出 12输入 3 4  输出 7 参考实现 function f(depth,count){ var states = new Arr

二叉树:小球下落

                          小球下落 [题目大意]            有一颗二叉树,最大深度为D,且所以叶子的深度都相同.所有结点从上到下       从左到右编号为1,2,3,....2^D-1.在结点1处放一个小球,他会往下落.每个内结点       上都有一个开关,初始全部关闭,当每次有小球落到一个开关时,状态会发生改         变.当小球到达一个内结点时,如果该结点上的开关关闭,则往左走,否则往右         走,直到走到叶子结点.如下图 [分析]

UVa679 小球下落(树)

UVa679 小球下落(树) 题目大意 小球从一棵所有叶子深度相同的二叉树的顶点开始向下落,树开始所有节点都为0.若小球落到节点为0的则往左落,否则向右落.并且小球会改变它经过的节点,0变1,1变0.给定树的深度D和球的个数I,问第I个小球会最终落到哪个叶子节点. 题意容易理解,紫书上给了一个模拟的做法,但这样会超时.后面的想法我觉得很巧妙. 每个小球都会落入根节点,第一个小球一定是向左,第二个向右,所以只看小球编号的奇偶性就可以知道它最终是落在哪一棵子树中.对于进入左子树的小球,通过判断其奇偶

Uva 679(Dropping Balls)小球下落

题目描述有一棵二叉树,最大深度为D,且所有叶子的深度都相同.所有结点从上到下从左到右编号为1,2,3,…,2D-1.在结点1处放一个小球,它会往下落.每个内结点上都有一个开关,初始全部关闭,当每次有小球落到一个开关上时,它的状态都会改变.当小球到达一个内结点时,如果该结点上的开关关闭,则往左走,否则往右走,直到走到叶子结点,如图所示. 一些小球从结点1处依次开始下落,最后一个小球将会落到哪里呢?输入叶子深度D和小球个数I,输出第I个小球最后所在的叶子编号.假设I不超过整棵树的叶子个数.D≤20.

UVa 679小球下落(二叉树的编号)

题意:二叉树按层次遍历从1开始标号,所有叶子结点深度相同,每个结点开关初始状态皆为关闭,小球从根结点开始下落(小球落在结点开关上会使结点开关状态改变),若结点开关关闭,则小球往左走,否则往右走,给定二叉树深度D,求第I个小球所落到的叶子结点编号. 分析:对于每一个结点,若小球当前编号为k, k为奇数,则这个小球是第(k+1)/2个落在此处的,则往左走; k为偶数,则这个小球是第k/2个落在此处的,则往右走; 从根结点到叶子结点需判断D-1次. 比如,假如I为15,则这是第15个落在根结点的小球,