Description
【解析】
对于一个结点 k,其左子节点、右子结点的编号分别是 2k 和 2k+1。
每个小球都会落在根结点上,因此前两个小球必然是一个在左子树,一个在右子树。一般地,只需看小球编号的奇偶性,就能知道它最终在哪棵子树中。对于那些落在根结点左子树的小球来说,只需知道该小球是第几个落在左子树里的,就可以知道它下一步往左还是往右了。依此类推,直至小球落在叶子上。
如果使用题目中给出的编号 I,则当 I 是奇数时,它是往左走的第 (I+1)/2 个小球;当 I 是偶数时,它是往右走的第 I / 2 个小球。这样,可以直接模拟最后一个小球的路线。
#include <cstdio>
using namespace std;
int main() {
int n;// n组数据
int D,I;// D层满二叉树,I个小球
while(scanf("%d", &n) != EOF && n != -1) {
while(n--) {
scanf("%d %d", &D, &I);
int k = 1; //k 表示小球所在的编号
// 模拟路径(只模拟最后一个球的路径即可)
for(int i = 0; i < D - 1; i++) {
if(I % 2)// 如果I为奇数,则向左子树移动 {
k *= 2;
I = (I+1) / 2;
}
else// I为偶数,则向右子树移动 {
k = k * 2 + 1;
I /= 2;
}
}
printf("%d\n", k);
}
}
return 0;
}