https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=8&problem=620&mosmsg=Submission+received+with+ID+17752885
称号:有一个完整的二叉树,每个节点是一个开关,最初的全封闭,球从顶点丢弃。
每次通过开关球将将其状态反转。现在先问k球落到d当层交换机经过号。
分析:进制编码。经过模拟几次能够看出,球会让开关形成连续二进制数的表示(根是低位)。
当放入第k个球时。开关状态正好是二进制的k。利用模2的余数推断走向就可以。
说明:观察规律模拟处理就可以。
超时:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 20;
int s[1<<maxn];
int main()
{
int n;
int D,I;
cin>>n;
while(n--)
{
memset(s,0,sizeof(s));
cin>>D>>I;
if(D==-1)
{
break;
}
int k,n=(1<<D)-1;
for(int i = 0;i<I;i++)
{
k=1;
while(1)
{
s[k]=!s[k];
k=s[k]?k*2:k*2+1;
if(k>n) break;
}
}
cout<<k/2<<endl;
}
return 0;
}
AC:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 20;
int main()
{
int n;
int D,I;
cin>>n;
while(1){
cin>>D;
if(D==-1)
break;
int k=1;
cin>>I;
for(int i= 0;i<D-1;i++)
if(I%2)
{
k=k*2;
I=(I+1)/2;
}
else
{
k=k*2+1;
I/=2;
}
cout<<k<<endl;
}
return 0;
}