一个二叉树的深度为D,有 I(i的大写) 个小球,每个小球依次从头结点开始下落,每个结点处有个开关,若开关关闭,则往左边走,若开关打开,则往右边走。求最后一个小球小落的最终位置。
输入多组数据,每组数据第一行为D(<=20) 和 I ,输出为最后小球位置(即所在的叶结点)。
方法一:
思想:若结点按层序遍历的编号为k,则其做孩子编号为k * 2,有孩子编号为k * 2 + 1。
代码如下:
#include <cstdio>
#include <cstring>
const int maxn = 20;
int str[1 << maxn];
int main()
{
int D,I;
while (scanf("%d %d",&D,&I) == 2)
{
memset(str,0,sizeof(str));
int i,n = (1 << D) - 1;
for (int j = 0; j < I; j++)
{
i = 1;
for (;;)
{
str[i] = !str[i];
i = str[i] ? 2 * i : 2 * i + 1;
if (i > n)
break;
}
}
printf("%d\n",i / 2);
}
return 0;
}
方法二:
通过找规律,根据 I 的奇偶性就可以判断:
代码如下;
#include <cstdio>
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)//若I为奇数
{
k *= 2;
I = (I + 1) / 2;
}
else
{
k = k * 2 + 1;
I /= 2;
}
}
printf("%d\n",k);
}
return 0;
}