679 - Dropping Balls

来源:互联网 发布:linux vim 新建文件 编辑:程序博客网 时间:2024/05/16 11:53

Dropping Balls

PS:因为该题排版较麻烦,这里给出OJ网址:UVa679 - Dropping Balls


有一棵二叉树,最大深度为D,且所有叶子的深度都相同。所有结点从上到下从左到右编号为1, 2, 3,…, 2D-1。在结点1处放一个小球,它会往下落。每个内结点上都有一个开关,初始全部关闭,当每次有小球落到一个开关上时,状态都会改变。当小球到达一个内结点时,如果该结点上的开关关闭,则往左走,否则往右走,直到走到叶子结点,如图6-2所示。

这里写图片描述

一些小球从结点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 <cstdio>// 该方法会超时// #include <cstring>// using namespace std;//const int maxDepth = 20;//// 树//int tree[1 << maxDepth];////int main() {//    // l组数据//    int l;//    // D层满二叉树,I个小球//    int D,I;//    scanf("%d", &l);//    while(l--) {//        scanf("%d%d", &D, &I);//        memset(tree, 0, sizeof(tree));//        // 最大结点编号//        int n = (1 << D) - 1;//        int k;//        for(int i = 0; i < I; i++) {//            // 结点当前位置//            k = 1;//            while(true) {//                // 置反//                tree[k] = !tree[k];//                // false->true,走左子树//                // true->false,走右子树//                if(tree[k]) {//                    k = k * 2;//                } else {//                    k = k * 2 + 1;//                }////                if(k > n) {//                    break;//                }//            }//        }//        // 最后一次的叶子节点编号//        printf("%d\n", k / 2);//    }//    return 0;//}int main() {    // l组数据    int l;    // D层满二叉树,I个小球    int D,I;    scanf("%d", &l);    while(l--) {        scanf("%d%d", &D, &I);        int k = 1;        // 模拟路径        for(int i = 0; i < D - 1; i++) {            // 如果I为奇数,则向左子树移动            // I为偶数,则向右子树移动            if(I % 2) {                k *= 2;                I = (I + 1) / 2;            } else {                k = k * 2 + 1;                I /= 2;            }        }        printf("%d\n", k);    }    return 0;}
0 0