【小练习】小球下落

文章目录

  • 1.练习代码
  • 2.关键点分析
    • 2.1题目
    • 2.2题目分析
    • 2.3代码走读
    • 2.4运行结果

1.练习代码

#include "stdafx.h"
#include <string.h>
#include <stdio.h>
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	const int MAXD = 10;
	int s[1<<MAXD];
	int D, I;
	while (scanf("%d%d", &D, &I))
	{
		int k = 1;
		for (int i=0; i<D-1; i++)
		{
			if (I%2) {k=k*2; I=(I+1)/2;}
			else {k=k*2+1; I/=2;}
		}
		printf("The result is:%d\n", k);
	}
	return 0;
}

2.关键点分析

2.1题目

有一棵二叉树,最大深度为D,且所有的叶子的深度都相同。
所有节点从上到下,从左到右编号为1,2,3,…,2的D次方-1.
在结点1处放一个小球,它会往下落。
每个结点上都有一个开关,初始全部关闭,当每次有小球落到一个开关上时,它的状态都会改变。
当小球到达一个结点,若开关关闭,则往左走;若开关打开,则往右走。
直到走到叶子结点。
【小练习】小球下落_第1张图片
一些小球从结点1处依次开始下落,最后一个小球会落在哪里?
输入叶子深度D和小球个数I,输出最后一个小球落在的叶子编号。

样例输入输出:
4 2
12
3 4
7

2.2题目分析

每个小球都会落在根节点上,因此前两个小球必然是一个在左子树,一个在右子树。
一般地,只需要看小球编号的奇偶性,就能知道它最终在哪棵子树中。

2.3代码走读

#include "stdafx.h"
#include <string.h>
#include <stdio.h>
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	const int MAXD = 10; //最大深度限制为10
	int s[1<<MAXD]; //叶子最大数量为2的10次方-1个
	int D, I;
	while (scanf("%d%d", &D, &I)) //输入深度,小球个数
	{
		int k = 1;
		for (int i=0; i<D-1; i++) //每一层作判断,看是进了左还是右
		{
			if (I%2) {k=k*2; I=(I+1)/2;} //如果最后一个小球需要时基数,则进左侧;否则进右侧。作完判断后将I重置为进入下一级的顺序号,继续下一轮判断。
			else {k=k*2+1; I/=2;}
		}
		printf("The result is:%d\n", k); //输出结果
	}
	return 0;
}

2.4运行结果

【小练习】小球下落_第2张图片

你可能感兴趣的:(数据结构)