Uva-679 Dropping Balls


题意:有一颗二叉树,最大深度为D,并且所有叶子的深度都相同。每一个叶子上都有一个开关。初始开关全都是关闭的。节点标    号从左到右,从上到下为1,2,......,2^D-1。结点1处放一个会下落的小球,每次落到叶子上,叶子上的开关就会改变。若开关是关闭的,则小球往左落下;若开关开启,则小球往右落下。

输入树的深度和小球个数,输出第I个小球最后所在的叶子编号。

一开始就感觉就是一个普通的模拟题,开一个容量为2^D-1的数组保存每个叶子上开关的状态即可。

以下是一开始写:

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#define maxn 20
#define PI 3.1415926536
using namespace std; 
int s[1<<maxn];
int main()
{
	//	std::ios::sync_with_stdio(false);
	int d,i,cas,k;
	scanf("%d",&cas);
	while(cas--)
	{
		scanf("%d%d",&d,&i);
			memset(s,0,sizeof(s));
			for(int j=0;j<i;j++)
			{
				k=1;
				while(1)
				{
					s[k]=!s[k];
					k=s[k]?2*k:2*k+1;
					if(k>(1<<d)-1)
						break;
				}	
			}
			printf("%d\n",k/2);
		}
	return 0;
} 

但是事情并没有这么简单。emmm。。。这样开数组由于运算量巨大会导致超时。

还有一种解法,因为开关只有两种状态,关或者开,所以小球不是往左走,就是往右走。

所以,当输入I的时候,可以通过判断I的奇偶性来确定小球的掉落方向。

代码如下:

#include<iostream>
#include<cstdio>
#include<map> 
#include<vector>
#include<queue> 
#include<stack>
#define maxn 10010
#define PI 3.1415926536
using namespace std; 
 
int main()
{
	//	std::ios::sync_with_stdio(false);
	int cas,d,i,k,j;
	scanf("%d",&cas);
	while(cas--)
	{
		scanf("%d%d",&d,&i);
		k=1;
		for(j=0;j<d-1;j++)
		{
			if(i%2) 
			{
				k=2*k;
				i=(i+1)/2;
			}
			else
			{
				k=2*k+1;
				i=i/2;
			}
		}
		printf("%d\n",k);
	}
	return 0;
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值