问题描述
任何一个正整数都可以用2进制表示,例如:137的2进制表示为10001001。
将这种2进制表示写成2的次幂的和的形式,令次幂高的排在前面,可得到如下表达式:137=27+23+2^0
现在约定幂次用括号来表示,即a^b表示为a(b)
此时,137可表示为:2(7)+2(3)+2(0)
进一步:7=22+2+20 (2^1用2表示)
3=2+2^0
所以最后137可表示为:2(2(2)+2+2(0))+2(2+2(0))+2(0)
又如:1315=210+28+2^5+2+1
所以1315最后可表示为:
2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)
输入格式
正整数(1<=n<=20000)
输出格式
符合约定的n的0,2表示(在表示中不能有空格)
样例输入
137
样例输出
2(2(2)+2+2(0))+2(2+2(0))+2(0)
题解:
首先解题的基本思路是转换为二进制,我第一反应就是想到用递归,在压栈的时候计算,在出栈的时候输出。模拟手算二进制的过程,这里有不懂的朋友可以百度一下,十进制转二进制的算法。大体思路有了,下面就是关键的格式控制了。
格式输出的坑及解决思路:
坑一:正确输出不同阶,比如10,有2^3和 2^1两个阶,如何衔接好2()的表示
坑二:阶内大于3的处理,只有0 1 2三个阶可以显示,比如2^7,就要对7再次递归并输出
坑三:这也是最让我头疼的问题,如何做到最后一个+号不输出,也就是判定什么时候是结尾。
我的思路是(要结合代码理解),对于原始未拆分的阶,就是10中拆一次的两个阶,设置一个布尔have来接收返回值,如果大阶存在并显示了,那么返回true告诉小阶,你前面要带+哦。
坑四:衔接坑3,这个大阶的返回要具有连贯性,就是不能通过return true来返回,假设4阶显示,而3阶没有,2阶有,那2阶得到的是3阶的false,不会带+号。
话不多说,上代码,代码可真TM简洁啊,我花了好多时间才写对(还是太菜了,继续努力吧)
#include<iostream>
using namespace std;
bool back(int i,int n){//i表示阶数,n表示当前
int flag=n%2;
n/=2;
bool have=false;
if(n>0){
have=back(i+1,n);
}
if(flag==1){
if(have)
cout<<"+";
if(i>2){//二次或多次分解
cout<<"2(";
have=back(0,i);
cout<<")";
}
if(i==0)
cout<<"2(0)";
else if(i==1)
cout<<"2";
else if(i==2)
cout<<"2(2)";
return true;
}
return have;//告诉后面带加号
}
int main(){
int n;
cin>>n;
back(0,n);//递归,启动!!!!
return 0;
}