洛谷P1010(递归法题解)

————————————本文旨在讨论计算机知识,欢迎指正——————————————

洛谷P1010(递归法题解)_第1张图片

输入输出样例

输入 

1315

输出 

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

说明/提示

【数据范围】

对于 100% 的数据,1≤n≤2×104。

 1≤n≤2×104

首先,我们观察这道题,笔者看到这道题一开始也是很懵,关于如何输出这种长长的一行,但是,我们经过拆解可以发现:

2的十次方,括号内是2加2的3次方,也就是8,根据括号中叠括号的方式,我们可以尝试用递归的方式来做题:

注意:2的0次方和2的一次方是特殊的,分别是最基础的奇数和偶数,其它数字都是这样合成的:

于是我们得把0和1次方作为终点;

那么,我们可以写出这样的函数:

void solve(int n)
{
    for (int i = 14; i >= 0; i--)
    {
        if (pow(2, i) <= n)
        {
            if (i == 0) {
                cout << "2(0)";//这里是对于2的0次方的断点
            }
            else if (i == 1)
            {
                cout << "2";//这里是对2的1次方的断点
            }
            else {
                cout << "2(";
                solve(i);//这个时候就是递归向下了,因为这个时候我们就要进行套括号的类似操作了
                cout << ")";
            }
            n -= pow(2, i);//拆解是线性相加来组成的,所以这里要-
            if (n != 0)cout << "+";
        }
    }
}

看到这里,也许你会有疑问:“为什么循环的次数是14次”,让我们看看这个题目的数据范围:“1≤n≤2×104” 

 那么,我们可以看看它最大到2的几次方,2的十四次方是16384,2的十五次方是32768,所以这里我们选取循环次数是14.并且,我们要从大到小开始循环,因为这个答案的形式是2的n次方从大到小开始的,所以我们要倒序遍历。

遍历到最后就拆成0和1了。

下面,我们来看看完成代码:

#include
#include
using namespace std;
int n;
void solve(int n)
{
    for (int i = 14; i >= 0; i--)
    {
        if (pow(2, i) <= n)
        {
            if (i == 0) {
                cout << "2(0)";
            }
            else if (i == 1)
            {
                cout << "2";
            }
            else {
                cout << "2(";
                solve(i);
                cout << ")";
            }
            n -= pow(2, i);
            if (n != 0)cout << "+";
        }
    }
}
int main()
{
    cin >> n;
    solve(n);
    return 0;
}

希望能对你有所帮助!

你可能感兴趣的:(每日一题,算法,线性回归,c++,学习,分类)