关于二叉树问题

有一颗二叉树,最大深度为D,且所有的叶子的深度都相同。所有结点从上到下从左到右标号为1,2,3,4…2^D-1。在结点1处放一个小球,它会往下落。每一个内结点上都有一个开关,初始值全部关闭,当每次小球落到一个开关上时,状态会发生改变。当小球达到一个内结点时,如果结点开关关闭,则往左,否则往右,知道走到叶子结点。一些小球从结点1处依次开始下落,最后一个小球会落到哪里,输入叶子深度D和小球个数I,输出第I个小球最后所在的叶子编号,假设I不超过整棵树的叶子个数。D <= 20。输入最多包含1000组数据

样例输入
4 2
3 4
10 1
2 2
8 128
16 12345

样例输出
12
7
512
3
255
36358

#include<stdio.h>
#include<string.h>

const int MAXD = 20;

int s[1<<MAXD];//最大结点个数为2^maxd-1 

int main()
 {
      int D, I;
      while(scanf("%d%d", &D, &I) == 2)
        {
            memset(s, 0, sizeof(s));        //首先将所有开关置0 
            int k, n = (1<<D)-1;            //n是最大的结点编号 
            for(int i = 0; i < I; i++)      //连续让I个小球下落 
            {
                k = 1;
                for(;;)
                {
                    s[k] = !s[k];
                    k = s[k] ? k*2 : k*2+1; //根据开关状态选择下落方向 
                    if(k > n) break;        //已经落 "出界"了 
                }
            }
            printf("%d\n", k/2);            //"出界"之前的叶子编号 
        }
      return 0;
 }

下面代码进行优化后节省下一个巨大数组的空间

#include<stdio.h>
int main() {
  int D, I;
  while(scanf("%d%d", &D, &I) == 2) 
  {
    int k = 1;
    for(int i = 0; i < D-1; i++)
      if(I%2) { k = k*2; I = (I+1)/2; }
      else { k = k*2+1; I /= 2; }
    printf("%d\n", k);
  }
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值