紫书题目小球下落

题意:给你一颗二叉树,这是一颗完全二叉树,给你这棵树的深度,这棵树是用来进行小球下落实验的树,小球从根节点开始下落,每次进过一个节点,这个节点的状态就会改变,起初所有的节点的状态都是关闭的,当一个小球经过的时候那么就会改变这个节点的状态。节点的状态分成两种,一种是关闭的,当一个节点的状态是关闭的时候,小球经过它就会向左走,相反的当这个节点的状态是打开的,那么这个小球就会向右走,现在给你一棵树的深度以及落下小球的个数,问你的是最后一个小球落在的叶子的编号是多少。

  书中是提供了两个方法的,其中一个就是通过模拟的方法进行,对每一个小球的下落进行模拟,通过一个标记数组来表示每一个节点的状态,不断的记录小球的落下编号,直到最后一个小球,
  还有就是通过找出这样的下落的规律,其实这样的下落是有一顶的规律的,当两个小球下落的时候一定是一个在根节点的左边一个在右边,于是或只要知道这个数据的奇偶性就可以知道最后一个球的下落的过程,从而知道他的下落的位置。每次通过一个节点都是一种重复的过程,可以把每一个节点看成根节点,这样就像是一个递归的过程。只要下落这棵树深度那么多次,就可以得出最后一个小球的编号。
源代码
#include<cstdio>
#include<cstring>
#include<iostream>
 
using namespace std;
const int maxn=1000+10;
 
int main()
{
    int D,I;
    while(scanf("%d%d",&D,&I)==2)
    {
        int k=1;
        for(int i=0;i<D-1;i++)
        {
            if(I%2)
            {
                k=2*k;
                I=(I+1)/2;
            }
            else
            {
                k=2*k+1;
                I=I/2;
            }
        }
        printf("%d\n",k);
    }
    return 0;
}
 
 
更加深的理解就是,通过每一次的找出这个小球是第几次通过这个节点来判断下一步这个小球是向什么方向进行下去,通过已知的某个节点的编号是k,那么这个节点的左孩子的编号就是2k,右孩子的编号就是2k+1.这样就可以通过计算每一个节点是通过的第几次来求出最后的一个小球到大的编号是多少。
原文地址:https://www.cnblogs.com/yewa/p/7243538.html