洛谷题解-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);
}
posted @ 2025-04-21 17:10  hardestnut  阅读(59)  评论(0)    收藏  举报