试题 算法训练 幂方分解
资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
任何一个正整数都可以用2的幂次方表示。例如:
137=27+23+20
同时约定方次用括号来表示,即ab 可表示为a(b)。
由此可知,137可表示为:
2(7)+2(3)+2(0)
进一步:7= 22+2+20 (21用2表示)
3=2+20
所以最后137可表示为:
2(2(2)+2+2(0))+2(2+2(0))+2(0)
又如:
1315=210 +28 +25 +2+1
所以1315最后可表示为:
2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)
输入格式
输入包含一个正整数N(N<=20000),为要求分解的整数。
输出格式
程序输出包含一行字符串,为符合约定的n的0,2表示(在表示中不能有空格)
提示:这道题与有一道2n次幂的表示差不多是一样的,我在那篇上面也写过思路了,那就再写一遍吧(有兴趣的也可以看看,和这道题几乎一样)。
思路:这道题用递归需要做,但是需要判断几个点,比如括号、加号和运算中不会出现比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(";
}
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){
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++;
}
}