一、解题思路
1、二进制表示法
为了知道一个数字是哪些(2)的幂组成,需要了解数字的二进制描述法,表示每一位是(1)还是(0)就可以知道如何用(2)的幂次方表示:
模板代码:
for (int i = 31; i >= 0; i--) //从大到小噢
if ((n >> i) & 1) { //如果本位上有数字1
此时可以分解出 2^i这个加法因子组成。
}
2、为什么是递归?
因为可能第一步分解出来的东东,还存在比(2)的数字,可能需要继续分解,这时就可以考虑使用递归。比如 (32=2^5),题目不让输出(5),还需要继续化简成嵌套的表现方式。
3、递归的出口
(2^0,2^1,2^2)都是出口,但从(2^3)开始就不行了,需要继续递归。
4、数据范围
本题的范围是(2*10^4=20000),上限是(2^{15}=32768),而(2^{14}=16384)就小于(20000)了,严格数据测试的话会WA掉,但本题出题人良心,没有给极限的测试数据,赞~
二、C++代码
#include <bits/stdc++.h>
using namespace std;
int n;
string dfs(int n) {
if (n == 0) return "0";
string res = "";
//遍历二进制的每一位
for (int i = 14; i >= 0; i--) {//从大到小噢
//13最后一个点会WA,14可以AC
//2^15=32768
//2^14=16384
//2^13=8192
//2*10^4=2*10000=20000
if ((n >> i) & 1) { //如果本位上有数字1
if (i == 1)//2^1需要写成2的形式,这是递归的出口
res += "2";
else {
//2^0,2^2,2^3...都需要写成2(n)的形式
res += "2(";
if (i > 2)//大于2的才需要再次分解,递归就可以了
res += dfs(i);
else//这里处理0和2的情况,它俩是一样的处理方式2(0),2(2),也就是2(to_string(i))
res += to_string(i);
//加上后扩号
res += ")";
}
//利用+号拼接在一起
res += "+";
}
}
//控制是不是显示最后的+号
if (res[res.size() - 1] == '+')res.pop_back();//最后一位是+号的,肯定是加多了,弹出去~
return res;
}
int main() {
cin >> n;
cout << dfs(n) << endl;
return 0;
}