一、题意
每组数组为一棵树,给出这个数的深度D,以及小球数量I。
每个球从一个二叉树根开始沿着树干下落,每经过一个结点会改变结点的开闭状态。所有结点的默认状态为关闭。关闭时小球往左走,否则往右走。
求每组数据中,第I个小球会落在那个叶子结点中。结点编号按层次遍历1到2^D-1。
二、解析
考察二进制的概念。假设是第I个小球,I从0开始算起的话,则I的二进制末位为0则往左走,1则往右走,每下一层I往右移一位。
然后根据树结点编号的计算方法即可算出答案。
三、代码
#include <iostream> using namespace std; int main() { int n, D, I, end; cin >> n; while(n --) { cin >> D >> I; D --, I --; long long ans = 1; while(D --) { if(I % 2) ans = ans * 2 + 1; else ans *= 2; I >>= 1; } cout << ans << endl; } cin >> end; }
四、归纳
- 主要复习了二进制,通常二进制可以结合状态压缩用来加快算法。
- 复习了树的操作。在从1开始层次遍历编号的书中,i * 2 + 1得到右子结点,i * 2得到左子节点。i / 2得到父节点。