3432. 二叉树
1
/ \
2 3
/ \ / \
4 5 6 7
/\ /\ /\ /\
... ...
如上图所示,由正整数 1,2,3,…1,2,3,… 组成了一棵无限大的(满)二叉树。
从任意一个结点到根结点(编号是 11 的结点)都有一条唯一的路径,比如从 55 到根结点的路径是 (5,2,1)(5,2,1),从 44 到根结点的路径是 (4,2,1)(4,2,1),从根结点 11 到根结点的路径上只包含一个结点 11,因此路径就是 (1)(1)。
对于两个结点 xx 和 yy,假设他们到根结点的路径分别是 (x1,x2,…,1)(x1,x2,…,1) 和 (y1,y2,…,1)(y1,y2,…,1),那么必然存在两个正整数 ii 和 jj,使得从 xixi 和 yjyj 开始,有 xi=yj,xi+1=yj+1,xi+2=yj+2,…xi=yj,xi+1=yj+1,xi+2=yj+2,…
现在的问题就是,给定 xx 和 yy,要求他们的公共父节点,即 xixi(也就是 yjyj)。
输入格式
1≤x,y≤231−11≤x,y≤231−1
输入样例:
10 4
输出样例:
2
代码:
二进制找不同
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
const int n = 1e6;
int a[n],b[n];
int sovle()
{
int k,kk;
cin >> k>>kk;
int len1=0,len2=0;
// map<int,int>mp1,mp2;
while(k)
{
if(k%2)
a[len1]=1;
len1++;
k/=2;
//cout <<a[len1-1]<<' ';
}
//cout << endl;
while(kk)
{
if(kk%2)
b[len2]=1;
len2++;
kk/=2;
//cout << b[len2-1]<<' ';
}
//cout << endl;
int cnt=0;
while(len1&&len2)
{
if(a[len1-1]==b[len2-1])
{
cnt*=2;
cnt+=a[len1-1];
}
else
return cnt;
len1--;
len2--;
/*cout <<a[len1]<<' '<<b[len2]<<endl;
cout<<len1<<endl;*/
}
return cnt;
}
int main()
{
cout<<sovle()<<endl;
}