码迷,mamicode.com
首页 > 其他好文 > 详细

二叉树:小球下落

时间:2016-05-07 11:19:34      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:

                          小球下落

【题目大意】

           有一颗二叉树,最大深度为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个0
int 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 2
3 4
10 1
2 2
8 128
16 12345
输出:
12
7
512
3
255
36358
*/





二叉树:小球下落

标签:

原文地址:http://blog.csdn.net/disparity_cjk/article/details/51328545

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!