63-小猴子下落
内存限制:64MB 时间限制:3000ms Special Judge: No
accepted:2 submit:5
题目描述:
有一颗二叉树,最大深度为D,且所有叶子的深度都相同。所有结点从左到右从上到下的编号为1,2,3,·····,2的D次方减1。在结点1处放一个小猴子,它会往下跑。每个内结点上都有一个开关,初始全部关闭,当每次有小猴子跑到一个开关上时,它的状态都会改变,当到达一个内结点时,如果开关关闭,小猴子往左走,否则往右走,直到走到叶子结点。
一些小猴子从结点1处开始往下跑,最后一个小猴儿会跑到哪里呢?
输入描述:
输入二叉树叶子的深度D,和小猴子数目I,假设I不超过整棵树的叶子个数,D<=20.最终以 0 0 结尾
输出描述:
输出第I个小猴子所在的叶子编号。
样例输入:
复制
4 2 3 4 0 0
样例输出:
12 7
分析:
1、到达某点的猴子个数如果是奇数,那么它下一个点将会往左走,同时到达这个点的猴子个数为:(n+1)/2;
2、到达某点的猴子个数如果是偶数,那么它下一个点将会往右走,同时到达这个点的猴子个数为:n/2;
3、模拟 (--D)次就可以得到答案
核心代码:
1 while(-- D) 2 { 3 if(T&1) 4 { 5 ans *= 2; 6 T = (T+1) / 2; 7 } 8 else 9 { 10 ans = ans * 2 + 1; 11 T /= 2; 12 } 13 }
C/C++代码实现(AC):
1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 #include <stack> 7 #include <map> 8 #include <queue> 9 #include <set> 10 11 using namespace std; 12 13 int main() 14 { 15 int D, T; // D深度, T猴子个数 16 while(scanf("%d%d", &D, &T), D || T) 17 { 18 int ans = 1; 19 while(-- D) 20 { 21 if(T & 1) 22 { 23 T = (T+1)>>1; 24 ans *= 2; 25 } 26 else 27 { 28 T = T >> 1; 29 ans = ans * 2 + 1; 30 } 31 } 32 printf("%d\n", ans); 33 } 34 return 0; 35 }