本题如果直接用数组模拟的话会超时。
每个小球都会落在根节点上,因此前两个小球必然是一个在左子树,一个在右子树。我们可以进一步的推广,如果有n个球落在根节点上,那么必然有(n+1)/2个球落在左子树上,n/2个球落在右子树上。一般的,只需看小球编号的奇偶性,就能知道它是最终在哪棵子树中。这样一层一层的进行判断,可以直接模拟最后一个小球的路线。
参考:算法竞赛入门经典(刘汝佳)
代码:
#include <stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int main()
{
int t;
while(~scanf("%d",&t) && t!=-1)
while(t--)
{
int d,k,tmp=1;
scanf("%d%d",&d,&k);
for(int i=1;i<d;i++)//判断第i层往哪走
{
if(k%2)
{
tmp=tmp*2;
k=(k+1)/2;//落到左子树的小球数(向上取整)
}
else
{
tmp=tmp*2+1;
k/=2;//落到右子树的小球数
}
}
printf("%d\n",tmp);
}
return 0;
}