小球下落(完全二叉树)

Problem D: 小球下落

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 66   Solved: 42
[ Submit][ Status][ Web Board]

Description

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

一些小球从结点1处依次开始下落,最后一个小球将会落到哪里?

Input

输入有多组,每组包含两个整数,叶子深度D和小球个数II不超过整棵树的叶子个数,D<=20。

Output

出第I个小球最后所在的叶子编号。

Sample Input

3 3
3 4

Sample Output

5
7

HINT

解题思路:

         I个小球依次从顶点开始下落,每到达一个节点,该节点的开关状态发生改变。当开关闭合时,小球向左走,反之向右走。D层数需要2^D-1个节点来构成完全二叉树

然后对每一个小球下落的过程进行模拟,这里我们可以用一个数组来表示开关的状态,初始状态开关均关闭,因此数组全部置为0,第一个小球从顶点开始下落,此时顶点的开关打开,小球向左走,小球的编号*2,若向右走,小球编号*2+1,继续这样向下走,当小球的编号大于最大编号时,说明,小球出界,结束循环,进行下一个小球的模拟,当最后一个小球出界时,结束循环,输出最后一个小球出界前的编号。

 

代码实现:

#include<iostream> 
#include<string.h> 
#include<cmath> 
#include<algorithm> 
using namespace std; 
const int MAX=1048576; 
int a[MAX]; 
int main() 
{ 
    int D,I,flag; 
    while(cin>>D>>I) 
    { 
          
        memset(a,0,sizeof(a)); 
        int max=pow(2,D)-1; 
        for(int i=0;i<I;i++) 
        { 
            flag=1; 
            while(1) 
            { 
                a[flag]=!a[flag]; 
                flag=a[flag]?flag*2:flag*2+1; 
                if(flag>max) 
                break; 
            } 
        } 
        cout<<flag/2<<endl; 
    } 
} 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值