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;
}
时间: 2024-10-14 05:37:06