算法竞赛入门经典_6数据结构基础
* 6.3 树和二叉树
** 小球下落问题
//小球下落问题 /* 有一棵二叉树,最大深度为D,且所有叶子的深度相同.所有节点从上到下从左到右 编号为1,2,3,4,...,2^D-1. 在节点1处放一小球,它会往下落.每个内节点上都有一个开关,初始全部关闭,当每次有 有小球落在开关上是,状态都会改变.当小球到达一个内节点时,如果该节点上的开关关闭, 则往左走,否则往右走,直到走到叶子结点. 一些小球从结点1处依次开始下落,最后一个小球会落到哪里呢? 输入: 叶子深度D和小球个数I 输出: 第I个小球最后所在叶子的编号 */ #include<cstdio> #include<cstring> const int maxd = 20; int s[1<<maxd]; //最大结点个数为2^maxd - 1 int main(){ int D, I; while(scanf("%d%d", &D, &I) == 2){ memset(s, 0, sizeof(s)); //开关 int k, n = (1<<D)-1; //n是最大结点编号 for(int i = 0; i < I; i++){ //连续让I个小球下落 k = 1; for(;;){ s[k] = !s[k]; k = s[k]?k*2:k*2+1; //根据开关选择下落方向 if(k > n) break; //已经落出界了 } } printf("%d\n", k/2); //出界之前的编号 } return 0; }
运行结果: