算法训练 2的次幂表示
时间限制:1.0s 内存限制:512.0MB
问题描述
任何一个正整数都可以用2进制表示,例如:137的2进制表示为10001001。
将这种2进制表示写成2的次幂的和的形式,令次幂高的排在前面,可得到如下表达式:137=2^7+2^3+2^0
现在约定幂次用括号来表示,即a^b表示为a(b)
此时,137可表示为:2(7)+2(3)+2(0)
进一步:7=2^2+2+2^0 (2^1用2表示)
3=2+2^0
所以最后137可表示为:2(2(2)+2+2(0))+2(2+2(0))+2(0)
又如:1315=2^10+2^8+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)
提示
用递归实现会比较简单,可以一边递归一边输出
#include <queue>
#include <functional>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <stack>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <assert.h>
#define REP(i,k,n) for(int i=k;i<n;i++)
#define REPP(i,k,n) for(int i=k;i<=n;i++)
#define scan(d) scanf("%d",&d)
#define scann(n,m) scanf("%d%d",&n,&m)
#define mst(a,k) memset(a,k,sizeof(a));
#define LL long long
#define eps 1e-8
#define INF 0x3f3f3f3f
#define mod 1000000007
using namespace std;
#define N 20
#define M 200000
void slit(int n)
{
bool num[N];
if(n==2){
cout<<2; //若为2,直接输出
return;
}
if(n==1){ //若为1,直接输出2(0)
cout<<"2(0)";
return;
}
int cot=0; //否则,进行分解
while(n){ //依次记录在 num[] 数组内
if(n&1) num[cot]=1;
else num[cot]=0;
cot++;
n>>=1;
}
bool flag = 0;
for(int i=cot-1;i>=0;i--){
if(num[i]){ //如果为1 表示存在 2^i
if(!flag) flag = 1; //第一个输出的数之前不用放 ‘+’
else cout<<"+";
if(i>=2){
cout<<"2(";
slit(i); //分解 i
cout<<")";
}else{ //如果是 第 0 位 或 第 1 位
slit(i+1); //方便输出 + 1
}
}
}
}
int main()
{
int n;
scan(n);
slit(n);
}