关于 幂次方 一题的思路+代码(递归)

题目来源:洛谷 P1010 [NOIP1998 普及组] 幂次方

题目描述

任何一个正整数都可以用2的幂次方表示。例如
137=27+23+20
由此可知,137可表示为:
2(7)+2(3)+2(0)
而7又可以表示为:2(2)+2+2(0)
3可以表示为:2+2(0)
因此137最终表示为:
2(2(2)+2+2(0))+2(2+2(0))+2(0)

输入描述

一个正整数n(n≤20000)。

输出描述

符合约定的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)

输入样例2

137

输出样例2

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

OP

\

思路

这道题要用递归来处理:

对于每一个大于2的数,都需要通过二进制将其拆为二的幂次和,对于每一个幂次再进行递归处理;

通过构建 tr[i] 来存储 i 的表达式;

通过处理二进制数和构建幂次栈来按顺序存储该数内含有2的哪些幂次,方便接下来的递归与构建字符串。

(对于(13)D,(1101)B,其幂次栈即为 { 3 , 2 , 0 } \{3,2,0\} {3,2,0},代表 13 = 2 3 + 2 2 + 2 1 13=2^3+2^2+2^1 13=23+22+21

还有一部分内容写在注释里了,方便理解。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

string tr[20004];//tr[i]存储i的表达式

string getst(int n)
{
    if(tr[n][0])return tr[n];//如果构建过串,直接输出
    stack<int>stk;//构建幂次栈
    int c=0,z=n;//z为n的一个拷贝,用于二进制处理;c记录处理到的二进制位数
    while(z)//构建幂次栈
    {
        if(z&1)stk.push(c);
        c++;
        z>>=1;
    }
    while(!stk.empty())
    {
        int z=stk.top();
        stk.pop();
        if(z!=1)//对于一般位,进行递归处理
        {
            tr[n]+="2(";
            tr[n]+=getst(z);//递归
            tr[n]+=')';
        }
        else tr[n]+='2';//如果n的二进制第1位为1,此时z=1,对字符串的贡献仅为‘2’
        if(!stk.empty())tr[n]+='+';//如果不是最右位,就添一个‘+’
    }
    return tr[n];
}

int main()
{
    tr[0]='0',tr[1]="1",tr[2]="2",tr[4]="2(2)";//初始化
    int n;
    cin>>n;
    cout<<getst(n);
    return 0;
}

初始化在函数外会RTE!

ED

\

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值