UVa OJ 679 - Dropping Balls
Posted SiuGinHung
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVa OJ 679 - Dropping Balls相关的知识,希望对你有一定的参考价值。
本题是一个二叉树问题——Perfect Binary Tree。
一个完美二叉树(PBT)的深度为D,从根结点开始,按层次遍历顺序编号为1,2,...,2D-1。
有若干个球,依次由根结点落下。当一个球落在非叶结点上时,将向左子树或右子树落下。这个方向由每一个结点的flag控制(其中,flag是一个0-1型变量):
①当flag==0时,小球向左子树运动;
②当flag==1时,小球向右子树运动。flag初始化为0。
一个小球路过该结点后,该结点的flag值变化。
求解第I个球最终到达的叶结点。
可以考虑模拟。直接模拟的时间复杂度为O(ID),空间复杂度为O(2D),多组数据下TLE。
值得注意的是,在题中的编号方式中,若一个结点的编号为k,则其左子结点的编号为2k,右子结点的编号为2k+1。
于是,可以考虑某一个结点k的情况:若某一个小球是第i个路过结点k的小球,则:
①当i为奇数时,小球向左,下一个结点为2k:此时,该小球是向左的第(i+1)/2个小球;
②当i为偶数时,小球向右,下一个结点为2k+1:此时,该小球是向右的第i/2个小球。
于是,可以直接模拟第I个球的路线。时间复杂度为O(D),空间复杂度为O(1)。
参考程序如下:
#include <stdio.h> int main(void) { int n, d, i; scanf("%d", &n); while (n--) { scanf("%d%d", &d, &i); int k = 1; d--; while (d--) { if (i & 1) { k = k << 1; i = i + 1 >> 1; } else { k = k << 1 | 1; i = i >> 1; } } printf("%d\n", k); } return 0; }
以上是关于UVa OJ 679 - Dropping Balls的主要内容,如果未能解决你的问题,请参考以下文章