CCF NOI1074. 2的幂次方表示 (C++)

版权声明:代码属于原创,转载请联系作者并注明出处。 https://blog.csdn.net/weixin_43379056/article/details/84998665

1074. 2的幂次方表示

题目描述

任何一个正整数都可以用2的幂次方表示。

例如:137=27+23+20。同时约定方次用括号来表示,即ab可表示为a(b)。由此可知,137可表示为:2(7)+2(3)+2(0)。进一步:7=22+2+20(21用2表示),3=2+20 。所以最后137可表示为:2(2(2)+2+2(0))+2(2+2(0))+2(0)

又如:1315=210+28+25+2+20
所以1315最后可表示为:2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)

输入

一个正整数n(n<=20000)。

输出

一行,符合约定的n的2的幂次方表示(在表示中不能有空格)。

样例输入

137

样例输出

2(2(2)+2+2(0))+2(2+2(0))+2(0)

数据范围限制

n<=20000

C++代码

#include <iostream>
#include <cassert>   // assert()
#include <cstring>   // memset()

using namespace std;

const int max_n   = 20000;  // maximum n
const int max_exp = 14;     // maximum exponent

int PowersOfTwoArray[max_exp+1];  // 2^14 = 16384

void findPresentationOfPowersOfTwo(int sum, int num, int *dp);
void printDetailedPresentation(int x, int *dp);
void handleMoreThanOneExponent(int exp);

int main()
{
    int n;

    cin >> n;

    assert(n>=1 && n<=max_n);

    // initialize array PowersOfTwoArray[]
    PowersOfTwoArray[0] = 1;
    for(int i=1; i<=max_exp; i++)
    {
        PowersOfTwoArray[i] = 2*PowersOfTwoArray[i-1];
    }
    
    // array dp saves power representation of 2    of n
    int *dp = new int[max_exp+1];

    memset(dp, 0, sizeof(int)*(max_exp+1));

    findPresentationOfPowersOfTwo(n, 1, dp);

    cout << endl;

    delete [] dp;

    return 0;
}

// if exponent is more than 1, continue to split and print
void handleMoreThanOneExponent(int exp)
{
    // array tmp_dp saves power representation of 2 of exp
    int *tmp_dp = new int[max_exp+1];

    memset(tmp_dp, 0, sizeof(int)*(max_exp+1));

    // use recursive method to find detailed presentation and print 
    findPresentationOfPowersOfTwo(exp, 1, tmp_dp);

    delete [] tmp_dp;
}

void printDetailedPresentation(int x, int *dp)
{
    for(int i=1; i<x; i++)
    {
        switch(dp[i])
        {
        case 0: 
            cout << "2(0)"; 
            break;

        case 1: 
            cout << "2"; 
            break;

        default: // dp[i] > 1
            cout << "2(";
            handleMoreThanOneExponent(dp[i]);
            cout << ")";
            break;
        }

        if (i != x-1)   // print "+" except last one
        {
            cout << "+";
        }
    }
}

void  findPresentationOfPowersOfTwo(int sum, int num, int *dp)
{
    if(0 == sum)
    {
        // print detailed presentation of powers of two
        printDetailedPresentation(num, dp);
        return ;
    }

    for(int i=max_exp; i>=0; i--)
    {
        if (PowersOfTwoArray[i] > sum)
        {
            continue;
        }
        
        if((num>1 && i<dp[num-1]) || num==1)
        {
            dp[num] = i;
            findPresentationOfPowersOfTwo(sum-PowersOfTwoArray[i], num+1, dp);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_43379056/article/details/84998665