二叉树:小球下落

来源:互联网 发布:三维仿真软件 编辑:程序博客网 时间:2024/04/30 09:35

                          小球下落

【题目大意】

           有一颗二叉树,最大深度为D,且所以叶子的深度都相同。所有结点从上到下       从左到右编号为1,2,3,....2^D-1.在结点1处放一个小球,他会往下落。每个内结点       上都有一个开关,初始全部关闭,当每次有小球落到一个开关时,状态会发生改         变。当小球到达一个内结点时,如果该结点上的开关关闭,则往左走,否则往右         走,直到走到叶子结点。如下图


【分析】

                    先将每个结点用数组保存标记,几个小球下落,就执行几次循环,每次执行,凡是到了哪个结点处就使      标记数组变化,使其下次可以指到不同的方向。

【代码实现】

代码  1:

#include<stdio.h>#include<string.h>const int maxd=20;int s[1<<maxd];  // 表示2^maxd,1的二进制数向左移动maxd位,即在1的二进制后面加了maxd个0int main(){    int D,I;    while(~scanf("%d %d",&D,&I))    // 输入叶子所在的深度D,和有多少个小球下落    {        memset(s,0,sizeof(s));        int k,n=(1<<D)-1;       // n为最大结点编号        for(int i=0;i<I;i++)        {            k=1;        // 从堆顶开始            for( ; ; )            {                s[k]=!s[k];    // 经过后改变活塞方向                k=s[k]? k*2:k*2+1;  // 判断往哪方向走                if(k>n)         // 越界跳出                    break;            }        }        printf("%d\n",k/2);    }    return 0;}

这个代码简单但数据太大就会超时,很适合了解小球下落的过程


代码  2:

#include<stdio.h>#include<string.h>int main(){    int D,I;    while(~scanf("%d %d",&D,&I))    {        int k=1;        for(int i=0;i<D-1;i++)  // 有D层,就遍历D次            if(I%2)         // I个小球到每一层时,只考虑第I个就行了,如果它为奇数它就往左走,如果它为偶数他就往右走        {            k=k*2;            I=(I+1)/2;        }        else        {            k=k*2+1;            I/=2;        }        printf("%d\n",k);    }    return 0;}/*输入:4 23 410 12 28 12816 12345输出:127512325536358*/





0 0