题链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=620

题意就是有一个球从二叉树的结点1开始下落,每个结点上有个开关,关闭时小球往左走,否则往右走,每次经过结点后改变开关。输入二叉树深度和小球个数,输出最后一个小球下落的结点。

一开始我把每个球的情况都算了一遍,然后就超时了。

后来参考了书上的代码,对于前两个小球来说必然一个在左个小球子树,一个在右子树。当i是奇数时,它是往左走的第(i+1)/2个小球,当它是偶数时,是往右走的第i/2小球。

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 
 5 int s[1 << 20];
 6 
 7 int main()
 8 {
 9     int d, i, n;
10     while (cin>>n && n>=0)
11     {
12         while (n--)
13         {
14             cin >> d >> i;
15             memset(s, 0, sizeof(s));
16             int k = 1;
17             for (int j = 0;j < d-1; j++)
18             {
19                 if (i % 2)  { k = k * 2; i = (i + 1) / 2; }
20                 else  { k = k * 2 + 1; i /= 2; }
21             }
22             cout << k << endl;
23         }
24     }
25     return 0;
26 }