洛谷题解-P1010 [NOIP 1998 普及组] 幂次方
题目描述
任何一个正整数都可以用 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)。
输入格式
一行一个正整数 n。
输出格式
符合约定的 n 的 0,2 表示(在表示中不能有空格)。
输入输出样例:
输入
1315
输出
2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)
说明/提示
【数据范围:对于 100% 的数据,1≤n≤2×10^4
思路:我们可以很容易表示出一个数的二次幂表示,但是这个幂有可能大于2,这会导致括号里面嵌套括号。那么该怎么输出呢?最开始考虑数组储存二次幂多项式,再找到'(',再对括号后面的数进行二次幂分解。但是数组大小是固定的,这样进行二次分解不好储存结果。
所以干脆考虑递归,这个递归函数传入一个数,直接输出数串在输出'('后,讨论'('后面的数(即幂)的大小,大于二进行递归即可
#include<stdio.h>
#include<math.h>
void break_down(int k){
int i=0;
//找到i的最高位,不用考虑超过了的情况,if(k>>i&1==1)这一句可处理这种情况
while(pow(2,i)<k)
i++;
for(;i>=0;i--){
//位运算,判断第i位是否为1
if(k>>i&1==1){
//k确定是否输出+,如果k为零说明分解结束,不用输出+
k-=pow(2,i);
//幂为0,1直接输出,为2及以上需要二次分解
if(i==0){
printf("2(0)");
if(k)printf("+");
}
else if(i==1){
printf("2");
if(k)printf("+");
}
else {
printf("2(");
break_down(i);
printf(")");
if(k)printf("+");
}
}
}
}
int main(){
int t;
scanf("%d",&t);
break_down(t);
}

浙公网安备 33010602011771号