当前位置:   article > 正文

【ZCMU1158】松哥的二叉树(模拟)_1158: 松哥的二叉树

1158: 松哥的二叉树

题目链接

1158: 松哥的二叉树

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 54  Solved: 45
[Submit][Status][Web Board]

Description

有一棵满二叉树,最大深度为D,且所有叶子的深度都相同。所有结点从上到下从左到右编号为1,2,3,…,2^D-1。松哥在结点1处放下一个小球,它会往下落。每个结点都会有一个开关,初始全为关闭,当每次有小球落到一个开关上时,开关的状态都会改变(开变关,关变开)。当小球到达某个结点时,如果该结点上的开关关闭,则小球往左走,否则往右走,直到走到叶子结点。现在有n个小球依次从结点1开始往下落,松哥想要知道第n个小球落在哪个结点,你能告诉他嘛?

 

Input

多组测试数据。每组测试数据包含两个整数D(D<=30),n(n<=2^D-1)。

 

Output

对于每组测试数据输出一个整数,代表最后一个小球最终下落在哪个结点。

 

Sample Input

4 1

4 2

4 3

Sample Output

8

12

10

 

【解题思路】

这题好像是道挺经典的题,我看紫书上也有,所以就写一下啦。

经过简单模拟可以发现如果下落的小球编号I是奇数,它是往左走的第(I+1)/2个小球,如果I是偶数,它是向右走的第I/2个小球。这样,可以直接模拟最后一个小球的路线。

这里简单说一下比如树有4层,求下落第7个球的位置。因为7是奇数,那么它是往左走的第4个小球到达2位置,此时,因为I是4是偶数,它是往右走的第2个小球,到达5位置,然后I是2是偶数,此时它是往右走的第1个小球,即最终到达11位置。

 

【代码】

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int main()
  4. {
  5. int d,n;
  6. while(~scanf("%d%d",&d,&n))
  7. {
  8. int k=1;
  9. for(int i=0;i<d-1;i++)
  10. {
  11. if(n%2)
  12. {
  13. k=k*2;
  14. n=(n+1)/2;
  15. }
  16. else
  17. {
  18. k=k*2+1;
  19. n=n/2;
  20. }
  21. }
  22. printf("%d\n",k);
  23. }
  24. return 0;
  25. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/1015405
推荐阅读
相关标签
  

闽ICP备14008679号