P1010 幂次方题解

题目传递门

一、解题思路

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;
}
原文地址:https://www.cnblogs.com/littlehb/p/15030495.html