小猴子下落问题

来源:互联网 发布:java true false 编辑:程序博客网 时间:2024/04/29 20:01

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

一些小猴子从结点1处开始往下跑,最后一个小猴儿会跑到哪里呢?

输入
输入二叉树叶子的深度D,和小猴子数目I,假设I不超过整棵树的叶子个数,D<=20.最终以 0 0 结尾
输出
输出第I个小猴子所在的叶子编号。
样例输入
4 23 40 0
样例输出
127

当看到这个题目时,首先想到的是完全二叉树的应用,因为题目中说所有叶子节点的深度都相同,然后就会联想到完全二叉树的一些性质:n为总结点数目

2*i<=n,则左孩子为2i,2*i>n,则无左孩子

2*i+1<=n,则右孩子为2i+1,否则无右孩子

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include<math.h>

//小猴子下落

int main() {
    int d,i,node,k,j,s[10010];
    //输入二叉树的深度以及小猴子的数目
    while(scanf("%d%d",&d,&i)==2)
    {
    //每次重新输入数据,得重新对s数组进行初始化为0,使用头文件string.h里面的memset函数就可以了,    
     memset(s,0,sizeof(s));    
    //node表示二叉树的总结点 2的d次方减1
    node=pow(2,d)-1;
    //printf("%d\n",node);
    for(j=1;j<=i;j++)
    {
       k=1;
       for(;;)
       {
           //描述小猴子走过之后的开关状态0-->关闭  1-->打开
             s[k]=!s[k];
            // printf("%d\n",s[k]);
             //如果s[k]!=0即s[k]等于1,也就是走之前为0,则便是关闭,向左走
          if(s[k]) k=k*2;
          else k=k*2+1;
          if(k>node)
             break;
       }
       
    }
     printf("%d\n",k/2);
  }
    return 0;
}

最后注意scanf的返回值表示正确输入参数的个数,等于2表示两个参数均正常输入,



 

0 0
原创粉丝点击