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 }

 

posted @ 2021-07-03 15:11  永远是个小孩子  阅读(63)  评论(0编辑  收藏  举报