NOI 1758
如图所示的二叉树,每个节点到根节点只有唯一一条路径,我们的任务是给出两个节点,找到它们的路径的第一个重合的节点。例如,4和10两个节点的路径分别是(4,2,1)和(10,5,2,1)所以第一个重合的节点是2,2就是我们要找的节点。
思路:这个二叉树的特点就是每个节点的左孩子是节点的二倍,右孩子是节点的二倍加1. 所以一个节点到根节点的路径只要不断除以2就行。每次循环,两个数较大的数除以二,直到两数相等,就是第一个重合节点了
代码:
#include<iostream>
using namespace std;
int main(){
int x,y;
cin>>x>>y;
while(1){
if(x == y){
cout<<x<<endl;
break;
}
else if(x<y)
y = y/2;
else
x = x/2;
}
return 0;
}
UVA 679
如图的二叉树,初始时每个节点都为false,之后有小球下落,落到某个节点上时,如果节点为false,小球向左落,如果节点为true,小球向右落,节点变为相反的值。给出树高D和下落小球数I,求第I个小球落到的叶节点。
思路:
某个节点第n次被小球砸到,如果n为奇数,那么小球往左落,如果n为偶数小球往右落。假设第八颗球,节点1被砸8次,对于节点1是向右落的。对于节点3,节点3被砸8/2=4次还是,向右落。依次类推。假设第7颗球,