[NOIP 1998 普及组] 幂次方
按二进制位从高到低拆分整数,对大于 1 的指数递归生成 0,2 表示。
OJ: luogu
题目 ID: P1010
难度:普及-
标签:递归二进制模拟python
日期: 2026-07-07 14:55
题意
把正整数写成若干个 2 的幂之和,并按题目规定输出:
2^0写成2(0);2^1写成2;2^k (k > 1)写成2(k 的同类表示)。
思路
任意正整数都可以按二进制拆成若干个 2^exponent。
从高位到低位扫描每个为 1 的二进制位:
- 指数为
0:输出2(0); - 指数为
1:输出2; - 指数大于
1:输出2(express(exponent))。
所有片段用 + 连接。
Python 知识
1 << power表示2^power。number >> exponent & 1判断某个二进制位是否为1。- 递归函数
express(number)返回字符串,外层只负责print。 - 先把片段放进
parts,最后"+".join(parts),避免处理最后一个加号。
参考笔记:
/home/rainboy/mycode/hugo-blog/content/program_language/python/math_tools.md/home/rainboy/mycode/hugo-blog/content/program_language/python/input_output_and_strings.md
代码
python
def express(number):
parts = []
power = 0
while (1 << power) <= number:
power += 1
for exponent in range(power - 1, -1, -1):
if number >> exponent & 1:
if exponent == 0:
parts.append("2(0)")
elif exponent == 1:
parts.append("2")
else:
parts.append(f"2({express(exponent)})")
return "+".join(parts)
n = int(input())
print(express(n))Guide 风格代码
cppbook《C++ 快速入门》教学风格的写法(std:: 前缀、i += 1 循环、0 起始下标):
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-08-14 14:55
* update_at: 2026-08-14 14:55
*/
#include <iostream>
// 输出 n 的题目规定表示,例如 1315 输出 2(2(2+2(0))+2)+...
void decompose(int n) {
if (n == 1) {
std::cout << "2(0)"; // 2^0 写成 2(0)
return;
}
if (n == 2) {
std::cout << "2"; // 2^1 直接写成 2
return;
}
// n <= 20000 < 2^15,所以只需要检查第 0 到第 14 位
bool first = true; // 第一个输出的项前面不需要加号
for (int bit = 14; bit >= 0; bit -= 1) {
if (((1 << bit) & n) == 0) {
continue; // 这一位是 0,不输出任何项
}
if (!first) {
std::cout << "+"; // 后面的项之前都要补一个加号
}
first = false;
if (bit == 0) {
std::cout << "2(0)";
} else if (bit == 1) {
std::cout << "2";
} else {
std::cout << "2(";
decompose(bit); // 指数也要按同样的规则递归分解
std::cout << ")";
}
}
}
int main() {
int n;
std::cin >> n;
decompose(n);
return 0;
}复杂度
n <= 20000,二进制位数很小。时间复杂度约为
总结
这题的核心是把数字的二进制分解和题目的递归输出规则对齐。用列表收集片段可以让输出格式更稳。