Dropping Balls UVA - 679题解(二叉树+模拟)

题目描述

A number of K balls are dropped one by one from the root of a fully binary tree structure FBT. Each
time the ball being dropped first visits a non-terminal node. It then keeps moving down, either follows
the path of the left subtree, or follows the path of the right subtree, until it stops at one of the leaf
nodes of FBT. To determine a ball’s moving direction a flag is set up in every non-terminal node with
two values, either false or true. Initially, all of the flags are false. When visiting a non-terminal node
if the flag’s current value at this node is false, then the ball will first switch this flag’s value, i.e., from
the false to the true, and then follow the left subtree of this node to keep moving down. Otherwise,
it will also switch this flag’s value, i.e., from the true to the false, but will follow the right subtree of
this node to keep moving down. Furthermore, all nodes of FBT are sequentially numbered, starting at
1 with nodes on depth 1, and then those on depth 2, and so on. Nodes on any depth are numbered
from left to right.
For example, Fig. 1 represents a fully binary tree of maximum depth 4 with the node numbers 1,
2, 3, …, 15. Since all of the flags are initially set to be false, the first ball being dropped will switch
flag’s values at node 1, node 2, and node 4 before it finally stops at position 8. The second ball being
dropped will switch flag’s values at node 1, node 3, and node 6, and stop at position 12. Obviously,
the third ball being dropped will switch flag’s values at node 1, node 2, and node 5 before it stops at
position 10.
Fig. 1: An example of FBT with the maximum depth 4 and sequential node numbers.
Now consider a number of test cases where two values will be given for each test. The first value is
D, the maximum depth of FBT, and the second one is I, the I-th ball being dropped. You may assume
the value of I will not exceed the total number of leaf nodes for the given FBT.
Please write a program to determine the stop position P for each test case.
For each test cases the range of two parameters D and I is as below:
2 ≤ D ≤ 20, and 1 ≤ I ≤ 524288.

Input

Contains l + 2 lines.
Line 1 l the number of test cases
Line 2 D1 I1 test case #1, two decimal numbers that are separated by one blank

Line k + 1 Dk Ik test case #k
Line l + 1 Dl Il test case #l
Line l + 2 -1 a constant ‘-1’ representing the end of the input file
Output
Contains l lines.
Line 1 the stop position P for the test case #1

Line k the stop position P for the test case #k

Line l the stop position P for the test case #l

Sample Input

5
4 2
3 4
10 1
2 2
8 128
-1

Sample Output

12
7
512
3
255

解题思路

题目大意就是给你一棵完全二叉树,每个节点的编号就是层序遍历这棵树的遍历顺序。
设当前节点的编号是k,那它的左节点的编号就是2 * k,它的右节点的编号就是2 * k+1,每一个节点都相当于一个开关,有两个状态,例如是开和关,默认每个节点的状态都是开,每个球落到当前节点时都会改变它的状态,如果当前节点的状态是开下一步就落到左节点,如果当前节点的状态是关下一步就落到右节点,直到落到树叶为止。
在这里插入图片描述
题目输入给你这棵树的深度和一共落下多少个小球
要求输出最后一个小球落到哪一片树叶上
因为数据规模过大,所以直接模拟会超时,所以此时我们就要找小球下落的规律

例如:求第5个小球落到第四层哪个树叶?
第一步:
——1,3,5号球会落到2号节点上
——2,4号球会落到3号节点上
第二步:
——1,5号球会落到4号节点上
——3号求会落到5号节点上
第三步:
——1号球会落到8号节点上
——5号球会落到9号节点上

分析一下,因为经过两次状态的切换节点状态会变成开。所以你只需判断最后一个球前面有多少个球落在当前节点上,所以只需判断一下奇偶性就知道往哪个方向走了。

如上例,5个球,因为5是奇数,共有(n+1)/ 2个球往左走,最后一个球往左走,ans * 2
有3个球往左走,3也是奇数,共有(n+1)/ 2个球往左走,最后一个球往左走,ans * 2
有2个球往左走,2是偶数,共有n / 2个球往右走,最后一个球往右走,(ans * 2)+1

代码

#include"bits/stdc++.h"
using namespace std;
int main(){
	int num,deep,ball,ans=1;
	scanf("%d",&num);
	while(num--){
		ans=1;
		scanf("%d%d",&deep,&ball);
		for(int i=1;i<deep;i++){
			if(ball%2){
				ans=ans*2;
				ball=(ball+1)/2;
			}else{
				ans=ans*2+1;
				ball/=2;
			}
		}
		printf("%d\n",ans);
	}
	int temp;
	scanf("%d",&temp);//这个吃个-1
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值