任何一个正整数都可以用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 3=2+2^0 (2^1用2表示)。所以最后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表示(在表示中不能有空格)
样例输入
1
|
137
|
样例输出
1
|
2(2(2)+2+2(0))+2(2+2(0))+2(0)
|
解答本题对原始数据进行按位操作是最好的选择首先,对于一个二进制表示的数:
eg:9=2^3+1写为二进制:1 0 0 1=1*2^3+0*2^2+0*2^1+1*2^0
下标:3 2 1 0 很明显一个二进制表示的数在转为十进制时指数就是当前位的下标!
注意原题:137=2^7+2^3+2^0 ==》 2(2(2)+2+2(0))+2(2+2(0))+2(0) 中间的变化只是对前一次的指数进一步的拆分(其形式为二进制转为十进制的计算式忽略0项)。而当前位的指数就是将该数转变为二进制时的下标。
#include<stdio.h>/*(try_fei_ge)*/
void e(int n)
{
int cur,i;/*cur为辅助下标控制将目前数完全拆分指向数i为当前下标数读出将要拆分的指数*/
for(i=0,cur=1;cur<=n;cur<<=1,i++); /*将cur指向最高位式输出由高位到低位*/
printf("2");/*目标式每一项必然以2为底数*/
for(;cur>0;cur>>=1,i--) /*便利二进制数每一位*/
if(cur&n) /*跳过为0位*/
{
if(cur>2) /*cur>2即当前指数大于2*/
{
printf("(");
e(i); /*拆分指数*/
printf(")");
}
if(cur==2) ; /*拆分至2时不用输出指数*/
else if(cur==1) printf("(0)");/*拆分至一时指数为0*/
if(n-=cur) printf("+2");/*解释在下*/
}
}
int main()
{
int a;
scanf("%d",&a);
e(a); /*将传入参数拆分为目标式*/
return 0;
}
if(n-=cur) printf("+2"); 在二进制数中每遍历一位就将这一位减去遍历完所有位时原数也将为0这时不再有下一位,否则就要输出+和下一项底数2.
程式中对1进行左移右移判断当前二进制位是否为1,并且用i纪录下标方便递归调用。避免了先将十进制数转换为二进制数的复杂步骤。
若有不足欢迎补充交流