2756:二叉树,考点:二叉树
原题:http://bailian.openjudge.cn/practice/2756/
描述
如上图所示,由正整数1, 2, 3, ...组成了一棵无限大的二叉树。从某一个结点到根结点(编号是1的结点)都有一条唯一的路径,比如从10到根结点的路径是(10, 5, 2, 1),从4到根结点的路径是(4, 2, 1),从根结点1到根结点的路径上只包含一个结点1,因此路径就是(1)。对于两个结点x和y,假设他们到根结点的路径分别是(x1, x2, ... ,1)和(y1, y2, ... ,1)(这里显然有x = x1,y = y1),那么必然存在两个正整数i和j,使得从xi 和 yj开始,有xi = yj , xi + 1 = yj + 1, xi + 2 = yj + 2,... 现在的问题就是,给定x和y,要求xi(也就是yj)。
输入
输入只有一行,包括两个正整数x和y,这两个正整数都不大于1000。
输出
输出只有一个正整数xi。
样例输入
10 4
样例输出
2
解法
思路:二叉树的性质。节点n的左儿子是2n,右儿子是2n+1
一开始自己写的思路:两个数中大的那个树先向上,与小的那个数停在同一层,然后两个节点再一起向上遍历,直到相同。
自己写的比较冗余的代码:
1 /*先变到同一层,再一起向上找*/ 2 #include <iostream> 3 using namespace std; 4 int getdepth(int n) 5 { 6 int i = 1; 7 while (n >= i) 8 i = 2 * i; 9 return i; 10 } 11 int main() 12 { 13 int x, y; 14 cin >> x >> y; 15 if (x == y) { 16 cout << x << endl; 17 return 0; 18 } 19 int mins = x < y ? x : y; 20 int maxs = x < y ? y : x; 21 int dep = getdepth(mins); 22 while (maxs >=dep)//变到同一层 23 maxs = maxs / 2; 24 while (mins!=maxs) { 25 mins = mins / 2; 26 maxs = maxs / 2; 27 } 28 cout << mins << endl; 29 return 0; 30 }
老师课上讲的方法,思路与我类似,但实现非常简便
1 #include <iostream> 2 using namespace std; 3 int main() { 4 int x, y; 5 cin >> x >> y; 6 while (x != y) { 7 if (x > y)x = x / 2; 8 else y = y / 2; 9 } 10 cout << x << endl; 11 return 0; 12 }
基于上面这个方法,也可以用递归来实现
1 #include <iostream> 2 using namespace std; 3 int common(int x, int y) 4 { 5 if (x == y)return x; 6 if (x > y)return common(x / 2, y); 7 else return common(x, y / 2); 8 } 9 int main() 10 { 11 int x, y; 12 cin >> x >> y; 13 cout << common(x, y) << endl; 14 return 0; 15 }