UVA 679 Dropping Balls(二叉树性质)

Dropping Balls

题意,有一颗完全二叉树,有好多球从根节点往下走,关于往左还是往右要看每个节点的开关,初始的话全部关闭,每走过一个节点,这个节点开关会改变一次,问最后一个球落在哪个叶子节点,给出编号(开关,反之往
这里有几个知识点

1. n &lt; &lt; m n &lt;&lt; m n<<m 写法等同与 n * 2m
2. 因为 + + +优先级比 &lt; &lt; , &gt; &gt; &lt;&lt; , &gt;&gt; <<,>>高,所以n * 2m+1要写为(n << m) + 1
3. 对于完全二叉树,每个节点 k k k 的左右节点为 2 k , 2 k + 1 2k, 2k+1 2k,2k+1

第一眼看的话很容易写出模拟版本的,模拟每一个小球,但是会超时
#include<bits/stdc++.h>
using namespace std;
const int N = 20;

int _, n, m;
int a[1<<N];		//1<<N即为1*2^n
					//最大节点数为2^n-1
int main()
{
	for (scanf("%d", &_); _; _--){
		cin >> n >> m;
		int maxn = (1 << n) - 1;			//最大节点数
		// cout << maxn << endl;
		memset(a, 0, sizeof(a));		//开关刚开始的时候为关闭,0
		int start;
		for(int i = 0; i < m; i++){		//连续让m个小球下落
			start = 1;
			while(start <= maxn){			//落出界后退出
				start = a[start] ? (start << 1) + 1 : start << 1;	//选择方向
				a[start>>1] = !a[start>>1];							//改变开关
			}
		}
		// cout << start << endl;
		cout << (start >> 1) << endl;	//输出节点start/2
	}
	cin >> _;
	return 0;
}
仔细思考下就会发现,对于每一个节点只要知道当前小球是第奇数个还是偶数个到达这个节点的,就可以判断往左走还是右。
  • 1 >>>> 左
  • 2 >>>> 右
  • 3 >>>> 左
  • … …
知道往左还是往右,就推出来是第几个到达子树了
  • 第D次到达父节点
  • 往左 >>>> 第 ( D + 1 ) / 2 (D+1)/2 D+1/2次到达左子树
  • 往右 >>>> 第 D / 2 D/2 D/2次到达右子树
那么我们就可以直接模拟最后的小球的路径了
#include<bits/stdc++.h>
using namespace std;
const int N = 20;

int _, n, m;
int main()
{
	for (scanf("%d", &_); _;_--){
		cin >> n >> m;
		int ans = 1;				//节点的编号
		for(int i = 0; i < n-1; i++){	//小球下降了n-1次,
										//第m个小球是第m个到达1节点的
			if(m&1){				//n为奇数
				ans = ans << 1;		//往左
				m = (m + 1) / 2;	//最后一个小球到达左子树是第几个到达的
			}else{	
				ans = (ans << 1) + 1;	//往右
				m = m / 2;			//最后一个小球到达右子树是第几个到达的
			}
		}
		cout << ans << endl;
	}
	cin >> n;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值