把 n 按二进制拆成 2 的幂之和,指数用同一个递归函数继续展开:指数 0 写 2(0)、指数 1 写 2、更大写 2(...),余项用 + 拼接。
OJ: roj
题目 ID: 1208
难度:普及-
标签:递归位运算模拟python
创建: 2026-09-29 23:37
更新: 2026-10-05 05:32
题目描述
任何一个正整数都能拆成 2 的幂之和。约定 2,2(0),2(...) 且指数 + 连接。如 2(2(2)+2+2(0))+2(2+2(0))+2(0)。
输入:一个正整数
样例输入:
text
137样例输出:
text
2(2(2)+2+2(0))+2(2+2(0))+2(0)思路
取 2(0)、2、2(expand(i)),再对剩余 + 拼接。指数的展开规则与
参考代码
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;
}