2的幂次方表示

GitHub跳转原题关系图返回列表

把 n 按二进制拆成 2 的幂之和,指数用同一个递归函数继续展开:指数 0 写 2(0)、指数 1 写 2、更大写 2(...),余项用 + 拼接。

OJ: roj

题目 ID: 1208

难度:普及-

标签:递归位运算模拟python

创建: 2026-09-29 23:37

更新: 2026-10-05 05:32

题目描述

任何一个正整数都能拆成 2 的幂之和。约定 212^1 写作 2,202^0 写作 2(0),2k (k≥2)2^k\ (k\ge 2) 写作 2(...) 且指数 kk 继续展开,项之间用 + 连接。如 137=27+23+20137=2^7+2^3+2^0 最终表示为 2(2(2)+2+2(0))+2(2+2(0))+2(0)。

输入:一个正整数 nn(n≤20000n \le 20000)。输出:一行,nn 的 0、2 表示,不含空格。

样例输入:

text
137

样例输出:

text
2(2(2)+2+2(0))+2(2+2(0))+2(0)

思路

取 xx 的最高位下标 i=⌊log⁡2x⌋i=\lfloor\log_2 x\rfloor,按 i=0i=0、i=1i=1、i≥2i\ge 2 分别写出 2(0)、2、2(expand(i)),再对剩余 x−2ix-2^i 递归并用 + 拼接。指数的展开规则与 xx 完全相同,同一个函数递归调用自身即可;x=0x=0 返回空串方便拼接。

参考代码

Python 版:

python
#!/usr/bin/env python3
# Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
# rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
# rainboy的学习导航网站: https://idx.roj.ac.cn
# create_at: 2026-09-29 23:37
# update_at: 2026-09-29 23:37

import sys


def expand(x: int) -> str:
    """把 x 写成约定的 0/2 表示,例如 5 -> 2(2)+2(0);x = 0 返回空串,方便递归拼接。"""
    if not x:
        return ''
    top = x.bit_length() - 1                    # 最高二进制位,即 x 中最大的那个 2 的幂的指数
    # 单个 2 的幂 2^top 的写法:指数 0 要显式写 2(0),指数 1 按约定直接写 2,更大则递归展开指数
    head = '2(0)' if top == 0 else '2' if top == 1 else f'2({expand(top)})'
    tail = expand(x - (1 << top))               # 去掉最高位后剩下的数,例如 137 - 128 = 9
    return head + f'+{tail}' * bool(tail)


def solve() -> None:
    n = int(sys.stdin.buffer.read())
    print(expand(n))


if __name__ == "__main__":
    solve()

C++ 版(同一算法):

cpp
/**
 * Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
 * rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
 * rainboy的学习导航网站: https://idx.roj.ac.cn
 * create_at: 2026-10-05 05:32
 * update_at: 2026-10-05 05:32
 */

#include <iostream>
#include <string>
using namespace std;

typedef long long ll;

// 把 x 展开成约定的 0、2 表示,例如 5 -> 2(2)+2(0);x=0 返回空串,方便拼接余项
string expand(ll x) {
    if (x == 0) {
        return "";
    }
    ll top = 0; // top 是 x 的最高二进制位下标,即最大那个 2 的幂的指数
    while ((1LL << (top + 1)) <= x) {
        top++;
    }
    string head; // 单个 2^top 的写法
    if (top == 0) {
        head = "2(0)"; // 2^0 必须显式写成 2(0)
    } else if (top == 1) {
        head = "2"; // 2^1 约定直接写 2
    } else {
        head = "2(" + expand(top) + ")"; // 指数自身继续展开
    }
    string tail = expand(x - (1LL << top)); // 去掉最高位后的剩余部分
    if (tail != "") {
        return head + "+" + tail;
    }
    return head;
}

int main() {
    ll n;
    cin >> n;
    cout << expand(n) << endl;
    return 0;
}