考研机试题:二叉树

描述

输入描述:

输入数据包括多行,每行给出一组测试数据,包括两个整数 m,n。

最后一行 0 0 表示输入结束。

输出描述:

对于每一组测试数据,输出一行,该行包含一个整数,给出结点 m 所在子树中包括的结点的数目。

输入

3 12
0 0

输出

4

代码

 #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    using namespace std;
    
    int main() {
        int m, n;
        while (1) {
            scanf("%d%d", &m, &n);
            if (m == 0 && n == 0) {
                break;
            }
    
            int i = 1; // 获取层数 从1开始
            int begin_level; // 存储子树的根在第几层
            int final_level; // 大树总共有几层
            // 2^(i-1) ~ 2^i-1
            // 1 << i ==> 2^i
            while (1) {
                if (m >= 1 << (i - 1) && m < 1 << i) {
                    begin_level = i;
                }
                if (n >= 1 << (i - 1) && n < 1 << i) {
                    final_level = i;
                    break;
                }
                ++i;
            }
            int left_side = m;
            int right_side = m;
            for (i = begin_level; i < final_level; ++i) {
                left_side = 2 * left_side;
                right_side = 2 * right_side + 1;
            }
    
            int treeNum;
            // left_side > n 说明 实际的最左最右孩子在倒数第2层
            // 子树 是一颗 从 begin_level ~ final_level-1 满二叉树
            if (left_side > n) {
                treeNum = (1 << (final_level - begin_level)) - 1;
            }
            else if (n <= right_side) {
                treeNum = (1 << (final_level - begin_level)) - 1;
                treeNum += n - left_side + 1;
            }
            else {
                treeNum = (1 << (final_level - begin_level + 1)) - 1;
            }
            printf("%d\n", treeNum);
        }
        return 0;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值