#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<math.h>
using namespace std;
int tree[1050000]; //0代表关 1代表开 这指开关情况
int main()
{
int n,k;
while(cin>>n)
{
if(n<0) break;
for(int i=0;i<n;i++)
{
int d,id,j;
cin>>d>>id;
memset(tree,0,sizeof(tree));
int len=(1<<d)-1;
for(j=1;j<=id;j++) //下放了j次
{
k=1;
for(;;) //遍历所有深度,注意是到d-1而不是d 就跪在这了
{
if(tree[k]==0)
{
tree[k]=1;k=2*k;
}
else
{
tree[k]=0;k=2*k+1;
}
if(k>len) break;
}
}
printf("%d\n",k/2);
}
}
return 0;
}
以上是刘汝佳的第一种做法 会造成TLE
<pre name="code" class="cpp">#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<math.h>
using namespace std;
int main() //不用数组就跪不了了,不用循环就跪不了了
{
int n,d,id;
cin>>n;
for(int j=0;j<n;j++)
while(scanf("%d%d",&d,&id)==2)
{
int k=1;
for(int i=1;i<d;i++) //不断判断下一个结点往左还是往右,最后一个结点不用判断,逗逼!
if(id%2) {k=k*2;id=(id+1)/2;} //它是往左走的第(id+1)/2个小球
else {k=k*2+1;id=id/2;} //它是往右走的第id/2个小球
printf("%d\n",k);
}
return 0;
}
以上是正确算法!只能说是好屌的算法,暂时一上手还是想不出来