九度 1095:2的幂次方

题目描述:

    Every positive number can be presented by the exponential form.For example, 137 = 2^7 + 2^3 + 2^0。

    Let's present a^b by the form a(b).Then 137 is presented by 2(7)+2(3)+2(0). Since 7 = 2^2 + 2 + 2^0 and 3 = 2 + 2^0 , 137 is finally presented by 2(2(2)+2 +2(0))+2(2+2(0))+2(0). 
 
    Given a positive number n,your task is to present n with the exponential form which only contains the digits 0 and 2.

思路

1. 蛮有意思的一道题, 拿来联系递归函数很好使

2. 题目的核心是递归函数, 而递归函数的核心又是退出条件. 从 137 这个案例可以看出, 当输入是 2 时, 返回 2 , 输入为 1 时返回 2(0). 起初, 我以为 2 的返回应该是 2(2(0)). 这就可以看出, 当 n = 2 时就已经需要退出了, n = 1 时, 自然更要退出了

 

3. 括号和加号的处理, 括号在父 DFS 加上(n==1 时例外), 加号由子DFS函数给出, 当 n = 0 时, 没有后续了, 就不用加号

4. 退出条件的位置. 一般来讲, 退出条件要放在 DFS 的上部分, 但这道题放在下面比较合适, 比如当 n = 3 时, 要写成 2 + 2(0)

代码

#include <iostream>
#include <stdio.h>
#include <string>
#include <cstring>
using namespace std;

int pow2[20];

void init() {
    pow2[0] = 1;
    for(int i = 1; i < 18; i ++) {
        pow2[i] = 2 * pow2[i-1];
    }

}

void dfs(int n, string &party) {
    for(int i = 16; i > 1; i --) {
        if(n >= pow2[i]) {
            party.push_back('2');
            party.push_back('(');
            dfs(i, party);
            party.push_back(')');
            n = n - pow2[i];
            if(n != 0)
                party.push_back('+');
        }
    }

    if(n >= 2) {
        party.push_back('2');
        n = n -2;
        if(n != 0)
            party.push_back('+');
    }
    if(n != 0) {
        party.append("2(0)");
        n = 0;
    }

}

int n;

int main() {
    freopen("testcase.txt", "r", stdin);
    init();
    while(scanf("%d", &n) != EOF) {
        string str;
        dfs(n, str);
        cout << str << endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/xinsheng/p/3592492.html