小球下落
【题目大意】
有一颗二叉树,最大深度为D,且所以叶子的深度都相同。所有结点从上到下 从左到右编号为1,2,3,....2^D-1.在结点1处放一个小球,他会往下落。每个内结点 上都有一个开关,初始全部关闭,当每次有小球落到一个开关时,状态会发生改 变。当小球到达一个内结点时,如果该结点上的开关关闭,则往左走,否则往右 走,直到走到叶子结点。如下图
【分析】
先将每个结点用数组保存标记,几个小球下落,就执行几次循环,每次执行,凡是到了哪个结点处就使 标记数组变化,使其下次可以指到不同的方向。
【代码实现】
代码 1:
#include
#include
const int maxd=20;
int s[1<
int main()
{
int D,I;
while(~scanf("%d %d",&D,&I)) // 输入叶子所在的深度D,和有多少个小球下落
{
memset(s,0,sizeof(s));
int k,n=(1<
for(int i=0;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
#include
int main()
{
int D,I;
while(~scanf("%d %d",&D,&I))
{
int k=1;
for(int i=0;i
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
*/