您的位置:首页 > 其它

关于二叉树问题

2017-04-06 18:59 99 查看
有一颗二叉树,最大深度为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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: