uva 122 小球下落 树的模拟
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; }