UVA - 679 Dropping Balls 【二叉树的编号】

Description

 

【解析】

对于一个结点 k,其左子节点、右子结点的编号分别是 2k 和 2k+1。

每个小球都会落在根结点上,因此前两个小球必然是一个在左子树,一个在右子树。一般地,只需看小球编号的奇偶性,就能知道它最终在哪棵子树中。对于那些落在根结点左子树的小球来说,只需知道该小球是第几个落在左子树里的,就可以知道它下一步往左还是往右了。依此类推,直至小球落在叶子上。

如果使用题目中给出的编号 I,则当 I 是奇数时,它是往左走的第 (I+1)/2 个小球;当 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;
}
发布了329 篇原创文章 · 获赞 342 · 访问量 17万+

猜你喜欢

转载自blog.csdn.net/Aibiabcheng/article/details/105479966