(小球下落)Dropping Balls UVA - 679
2018-02-13 07:56
495 查看
题目链接:Dropping Balls UVA - 679
题目:有一颗二叉树,最大深度为D,且所有叶子深度相同,所有结点从上到下、从左到右编号为1,2,3,4,5,….2D−12D−1。在结点1处放一个小球,它会往下落。每个内结点都有一个开关,初始全部关闭,当每次有小球落到一个开关上时,状态都会改变。当小球到达一个内结点时,如果该结点上的开关关闭,则往左走,否则往右走,知道走到叶子结点,如图所示:
一个小球从结点1依次开始下落,最后一个小球将会落在哪里呢?输入叶子深度D和小球个数I,输出第I个小球最后所在的叶子编号。假设I不超过整棵树的叶子个数。D<=20。输入最多包含1000组数据。
思路:不难发现,对于一个结点kk,其左子结点、右子结点的编号分别是2k2k和2k+12k+1。这个结论非常重要。。。模拟一下。。。
上面的代码TLM了。。。。运算量太大。
每个小球都会落在根结点上,因此前两个小球必然一个在左子树,一个在右子树。一般的只需要看小球编号的奇偶性,就能知道它最终落在哪棵子树中。对于那些落入根结点左子树的小球来说,只需要知道该小球是第几个落在根的左子树里的,就可以知道它下一步往左还是往右了。以此类推,知道小球落到叶子上。
当I是奇数时,它是往左走的第(I+1)/2个小球;当I是偶数时,它是往右走的第I/2个小球。这样就能模拟小球的路线了。
题目:有一颗二叉树,最大深度为D,且所有叶子深度相同,所有结点从上到下、从左到右编号为1,2,3,4,5,….2D−12D−1。在结点1处放一个小球,它会往下落。每个内结点都有一个开关,初始全部关闭,当每次有小球落到一个开关上时,状态都会改变。当小球到达一个内结点时,如果该结点上的开关关闭,则往左走,否则往右走,知道走到叶子结点,如图所示:
一个小球从结点1依次开始下落,最后一个小球将会落在哪里呢?输入叶子深度D和小球个数I,输出第I个小球最后所在的叶子编号。假设I不超过整棵树的叶子个数。D<=20。输入最多包含1000组数据。
思路:不难发现,对于一个结点kk,其左子结点、右子结点的编号分别是2k2k和2k+12k+1。这个结论非常重要。。。模拟一下。。。
#include<iostream> #include<string> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include<stack> #include<map> #include<iomanip> #define ll long long using namespace std; const int maxn = 20+7; int s[1<<maxn]; int main() { int D,I,t; scanf("%d",&t); while(t--) { scanf("%d%d",&D,&I); memset(s, 0, sizeof(s)); int k, n = (1<<D) - 1; for(int i = 0; i < I; i++) { k = 1; while(1) { s[k] = !s[k]; k = s[k] ? 2*k : 2*k + 1; if(k > n) break; } } printf("%d\n",k/2); } return 0; }
上面的代码TLM了。。。。运算量太大。
每个小球都会落在根结点上,因此前两个小球必然一个在左子树,一个在右子树。一般的只需要看小球编号的奇偶性,就能知道它最终落在哪棵子树中。对于那些落入根结点左子树的小球来说,只需要知道该小球是第几个落在根的左子树里的,就可以知道它下一步往左还是往右了。以此类推,知道小球落到叶子上。
当I是奇数时,它是往左走的第(I+1)/2个小球;当I是偶数时,它是往右走的第I/2个小球。这样就能模拟小球的路线了。
#include<iostream> #include<string> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include<stack> #include<map> #include<iomanip> #define ll long long using namespace std; const int maxn = 20+7; int main() { int D,I,t; scanf("%d",&t); while(t--) { scanf("%d%d",&D,&I); int k = 1; for(int i = 0; i < D - 1; i++) { if(I % 2) { k = 2*k; I = (I+1)/2;} else {k = k*2 + 1; I /= 2;} } printf("%d\n",k); } return 0; }
相关文章推荐
- Dropping Balls UVA - 679
- UVa679 小球下落(树)
- UVA-679小球下落
- 例题 6-6 小球下落(Dropping Balls) UVa 679 二叉树规律
- UVa679: dropping balls
- uva-679 小球下落
- UVa-679 - Dropping Balls
- 【UVa-679】小球下落——二叉树的编号
- uva 679 - Dropping Balls
- 小球下落 UVa 679
- Dropping Balls 小球下落 UVA 679
- 小球下落 UVa679
- 6_6 小球下落(UVa679)<完全二叉树编号>
- 例题6-6 小球下落(Dropping Balls, UVa 679)
- Dropping Balls UVA - 679
- UVa-679 小球下落
- uva 679 小球下落
- UVa 679 小球下落 简单模拟题,树
- UVa 679 例题6-6 小球下落(Dropping Balls)
- 算法竞赛入门经典第六章例题6-6 Dropping Balls UVA - 679