洛谷-P1010-幂次方-普及(摁写+递归/二进制+递归)

一 题目描述

二 示例及提示

输入格式

一行一个正整数 n。

输出格式

符合约定的 n的 0,2 表示(在表示中不能有空格)。

输入输出样例

输入 #1

1315

输出 #1

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

三 题解

1.直接按题意递归处理

思路:

代码:

#include <iostream>
#include <cmath>
using namespace std;

const int a = 2;

void confirm(int x)
{
    // 先无脑输出一个2,因为输入范围不存在小于1的数
    if(x != 0)
        cout<< "2";
    else    return;
    // 先找最接近x的k次幂
    int k = log(x)/log(a);
    //处理k部分 讨论k=1 =2 =0 和其他情况
    if(k == 2){
        cout << "(2)";
    }else if(k == 0){
        cout << "(0)";
    }else if(k > 2){
        // 若次幂大于2,则也要递归处理
        cout << "(";
        confirm(k);
        cout << ")";
        // 注意括号的先后输出
    }
    // 余数remainder
    int remainder = x - pow(a,k);
    // 处理余数部分
    if(remainder){
        cout << "+";
        confirm(remainder);
    }
}

int main()
{
    int x;
    cin >> x;
    confirm(x);
    return 0;
}

另:

exp(n) 为e^n;

log() 以e为底

log10() 以10为底

2.二进制+递归

以下题解基本来自洛谷原题里的题解区Delva大佬的解答。

#include <iostream>
using namespace std;

string confirm(int x)
{
    if(x == 0)
        return "0";
    int i = 0;
    string s = "";
    do{
        if(x & 1){
            s = (i == 1? "2":"2("+confirm(i)+")") + (s == ""? "":"+") + s;
        }
    }while(i++,x>>=1);
    return s;
}

int main()
{
    int x;
    cin >> x;
    cout << confirm(x) ;
    return 0;
}

写了一点我理解的思路就是:首先要明白二进制就是表示一个正整数分解为2的幂次方和,然后对于用户输入的数字x,我们可以让x每次右移1,同时设立一个计数器i来计算其右移的次数,而while的终止条件就是从低位到高位直到遍历完x的最高位,我们每次用字符串来保存遍历的结果,同时后一次遍历得到的字符串要拼接上前一次的字符串,并且要注意后一次的必须写在前面,因为它的次方更大。而且如果是遍历的第一遍,当字符串为空的时候,当然我们就不需要填写加号了,因此可以用三元运算符判断s是否为空串,如果是的话就不加加号,不是则需要加上。接下来是重点——对字符串拼接的设计,具体如图。

二进制位上的数不是1就是0,为0时不用做任何处理,因此我们只用考虑位上数字为1的情形。而且如图会发现,只有当i=1时,2后面是不用跟括号的,把这个情况做特殊处理,用一个三目运算符,讨论这两种情况,而括号里的数字我们则再进行递归处理,当i==0时,我们在函数开始部分用判断语句返回一个"0"。

注:>>= 相当于右移后赋值,例如x>>=3,就是将x右移3位后得到的结果再赋值给原来的变量x。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值