Codeforces Round #287 (Div. 2) C. (构造)

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

Input consists of two integers h, n (1 ≤ h ≤ 50, 1 ≤ n ≤ 2h).

Output

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.

Sample test(s)
Input
1 2
Output
2
Input
2 3
Output
5
Input
3 6
Output
10
Input
10 1024
Output
2046
Note

A perfect binary tree of height h is a binary tree consisting of h + 1 levels. Level 0 consists of a single node called root, level h consists of 2h nodes called leaves. Each node that is not a leaf has exactly two children, left and right one.

Following picture illustrates the sample test number 3. Nodes are labeled according to the order of visit.

                                                                              

题意:给出一棵高度为h+1的完全二叉树,要求得到从根节点到最后一行第n个节点需要走的步数。

            遵循的规则是:左右左右交替走;如果当前节点走过,则跳过不计入步数中。

思路:一开始的想法是完全的遍历,直到找到那一个节点,所以妥妥地T了。因为maxH是50,意味这我这样的算法最坏的情况是走2的50次方次。

            RightWay:将最后一行的节点总数进行二分,判断节点n是在当前查找位置的左边还是右边,目的在于不断的具体n的位置。

                                 1. 当n处于查找变量cnt的右边,且此刻方向往左,则加上左边子树的节点数。否则需改变方向。

                                 2. 当n处在查找变量cnt的左边,且此刻方向往右,则加上右边子树的节点数。否则需改变方向。

                                 3. 题目为h高度一层一层地往下查找,当到达最后一层的时候即h=0时,跳出循环。再进入下一层的时候需加上父节点。

                                 4. 数为long long 时不能用pow,可能会产生精度误差。pow 用的范围是int,double。

CODE:

#include <iostream>
#include <cstdio>
#include <cmath>

using namespace std;
typedef long long ll;
ll cal(ll a, ll b)
{
    ll s = 1;
    for(int i = 1; i <= b; ++i) {
        s *= a;
    }
    return s;
}
int main()
{
//freopen("in", "r", stdin);
    ll h, n, slast, cnt, ans;
    while(~scanf("%lld %lld", &h, &n)) {
        ans = 0; cnt = 0;
        int des = 0; //左边0,右边1
        slast = cal(2, h);
        while(h) {
            slast /= 2;
            if(n > cnt + slast) {
                cnt += slast;
                if(!des) {
                    ans = ans + cal(2, h) - 1;
                }

                else des = 1 - des;
            }
            else {
                if(des) {
                    ans = ans + cal(2, h) - 1;
                }
                else des = 1 - des;
            }
            h--;
            ans++;
        }
        printf("%lld\n", ans);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值