试题 算法训练 2的次幂表示
资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
任何一个正整数都可以用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)
样例输入
1315
样例输出
2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)
提示
用递归实现会比较简单,可以一边递归一边输出
思路:这道题提示用递归确实好点,但是需要判断几个点,比如括号、加号和运算中不会出现比2大的数字,一对括号中最大所出现的值为7,2的平方、本身和零次方,所以当出现比7还要大的数时就需要一对括号了,括号外加号的判断方法是只要所输入的数减去前面以及进行运算的数不为零就行,毕竟当全部表达完成之后就不需要进行运算了,也就没有加号了,这道题可以用数字0、1、2来表示计算,递归计算起来就很方便,直接根据没次递归所给数判断值为多少就行。
代码如下:
#include<iostream>
#include<cmath>
using namespace std;
void pow2n(int i){
int x=0,y,y1=i;
if(y1>2){
cout<<"2("; //只要次数大于2,数值大于5,就肯定有两对或两对以上在相加
}
while(i>0){
if(pow(2,x)>i){
if((x-1)<=2 && (x-1)>=0){
if((x-1)==1){
cout<<"2";
} else if((x-1)==2 || (x-1)==0){
cout<<"2("<<x-1<<")";
}
}else{
pow2n(x-1);
}
i=i-pow(2,x-1);
if(i!=0){
cout<<"+";
}
x=-1;
} else if(pow(2,x)==i){
if(x<=2 && x>=0){
if(x==1){
cout<<"2";
} else if(x==2 || x==0){
cout<<"2("<<x<<")";
}
}
else{
pow2n(x);
}
i=i-pow(2,x);
x=-1;
}
x++;
}
if(y1>2){
cout<<")";
}
}
int main(){
int n,i=0,j,k;
cin>>n;
while(n>0){
j=pow(2,i);
if(j>n){
n=n-pow(2,i-1);
if((i-1)==1 || (i-1)==2){
if((i-1)==1){ //当出现0、1、2三个数字时我会直接运算出结果,不递归,因为当1次给过去的时候就变成0次了
cout<<"2";
}
if((i-1)==2){
cout<<"2(2)";
}
}
else{
pow2n(i-1);
}
i=-1;
cout<<"+";
}
else if(j==n){
n=n-pow(2,i);
if(i==0){
cout<<"2(0)";
}
else{
pow2n(i);
}
i=-1;
}
i++;
}
}