Amr bought a new video game "Guess Your Way Out!". The goal of the game is to find an exit from the maze that looks like a perfect binary tree of height h. The player is initially standing at the root of the tree and the exit from the tree is located at some leaf node.
Let's index all the leaf nodes from the left to the right from 1 to 2h. The exit is located at some node n where 1 ≤ n ≤ 2h, the player doesn't know where the exit is so he has to guess his way out!
Amr follows simple algorithm to choose the path. Let's consider infinite command string "LRLRLRLRL..." (consisting of alternating characters 'L' and 'R'). Amr sequentially executes the characters of the string using following rules:
- Character 'L' means "go to the left child of the current node";
- Character 'R' means "go to the right child of the current node";
- If the destination node is already visited, Amr skips current command, otherwise he moves to the destination node;
- If Amr skipped two consecutive commands, he goes back to the parent of the current node before executing next command;
- If he reached a leaf node that is not the exit, he returns to the parent of the current node;
- If he reaches an exit, the game is finished.
Now Amr wonders, if he follows this algorithm, how many nodes he is going to visit before reaching the exit?
Input consists of two integers h, n (1 ≤ h ≤ 50, 1 ≤ n ≤ 2h).
Output a single integer representing the number of nodes (excluding the exit node) Amr is going to visit before reaching the exit by following this algorithm.
1 2
2
2 3
5
3 6
10
10 1024
2046
题意:给出n,给出一颗高度为h+1的完全二叉树,对于每一行的元素左到右,从1到2^h标号。刚开始位于root,然后按左右左右交替的走。
1.如果当前目的地走过了,他会跳过当前指令.
2.如果连续的跳过两条指令,他会回到父节点.
3.如果到达一个不存在的点,他会回到父节点
4.到达标号为n的点,他就赢了.
求中途经过点的个数。
动手画画,可以发现,如果他是由父亲直接走过来,他经过的点的个数就是经过他父亲的个数加1.否则就是他的兄弟节点走完,在走完父亲节点在加1.因为要求的是途中经过,最后要减去本身的1个点。然后递归求解即可。注意从第一层到第二层,奇偶性相同的是直接由父亲走过去,其他的则是有奇偶性不同的直接走过去。
#include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <set> #include <bitset> #include <queue> #include <stack> #include <string> #include <iostream> #include <cmath> #include <climits> using namespace std; typedef long long LL; LL h; LL cifang(LL x,LL y) { LL ans =1; for(LL i = 0;i<y;i++) ans*=x; return ans; } LL gao(LL x,LL y) { LL t = (y+1)/2; if(x==1) return 1; if(x==2){ if(y==1){ return 2; } else return cifang(2,h-x+1) + 1; } if(t%2==y%2){ LL k = cifang(2,h-x+1)+gao(x-1,t); return k; } else return 1+gao(x-1,t); } int main() { LL n; cin>>h>>n; h++; LL ans = 100; for(LL i = 1;i<=h;i++){ LL t = cifang(2,i-1); if(t>=n){ ans = i;break; } } LL Min = (1LL<<60); // for(LL i = ans;i<=h;i++){ // Min = min(Min,gao(i,n)); //cout<<i<<" "<<Min<<endl; //} cout<<gao(h,n)-1<<endl; return 0; }