题意:遍历一棵满二叉树,遍历方法是左右左右递归地遍历。树高度为h,最下层第n个节点是出口,问访问到出口前要访问多少个节点。
思路:按题目要求的顺序去递归遍历,判断出口在以当前节点为根的左子树还是右子树中,如果是在后访问的子树中,直接加上2^h,因为根加上另一颗子树刚好有2^h个节点,再往下递归。
#include <iostream>
#include <stdio.h>
#include <string>
#include <map>
#include <vector>
#include <stack>
#include <queue>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
#define ll long long
ll pow2n[55];
//falg=0:先访问左孩子 //flag=1:先访问右孩子
//h表示当前子树高度 n表示出口是第几个叶子
ll fun(ll h,bool flag,ll n){
if(h==0)return 1LL;
if(flag==0){
if(n>pow2n[h-1]){
return fun(h-1,0,n-pow2n[h-1])+pow2n[h];
}else{
return fun(h-1,1,n)+1;
}
}else{
if(n>pow2n[h-1]){
return fun(h-1,0,n-pow2n[h-1])+1;
}else{
return fun(h-1,1,n)+pow2n[h];
}
}
}
int main(){
//计算2的幂
pow2n[0]=1;
for(int i=1;i<=50;i++){
pow2n[i]=pow2n[i-1]<<1;
}
ll h,n;
cin>>h>>n;
ll ans=fun(h,0,n);
cout<<ans-1<<endl;
return 0;
}