UVa679 小球下落(树)
题目大意
小球从一棵所有叶子深度相同的二叉树的顶点开始向下落,树开始所有节点都为0。若小球落到节点为0的则往左落,否则向右落。并且小球会改变它经过的节点,0变1,1变0。给定树的深度D和球的个数I,问第I个小球会最终落到哪个叶子节点。
题意容易理解,紫书上给了一个模拟的做法,但这样会超时。后面的想法我觉得很巧妙。
每个小球都会落入根节点,第一个小球一定是向左,第二个向右,所以只看小球编号的奇偶性就可以知道它最终是落在哪一棵子树中。对于进入左子树的小球,通过判断其奇偶性也可以判断它会继续向左还是向右。依此类推,直到小球落到叶子上。
1 #include<iostream> 2 using namespace std; 3 int main() 4 { 5 int n; 6 while(cin>>n && n != -1) 7 { 8 while(n--) 9 { 10 int D,I;///D为叶子深度,I为小球个数 11 cin>>D>>I; 12 int deep = 1; 13 int ans = 1; 14 while(true) 15 { 16 deep++; 17 if(I%2)///第一个进入 18 { 19 ans *= 2;///向左走 20 I = (I + 1)/2; 21 }else{///第二个进入 22 ans = ans*2 + 1; 23 I = I/2; 24 } 25 if(deep == D)///到达叶子节点 26 { 27 cout<<ans<<endl; 28 break; 29 } 30 } 31 } 32 } 33 34 return 0; 35 }