2的次数幂表示整数

描述

任何一个正整数都可以用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表示(在表示中不能有空格)。

样例输入

137

样例输出

2(2(2)+2+2(0))+2(2+2(0))+2(0)

解题思路:这是一个很明显的递归问题,137由2(7)+2(3)+2(0) 到
2(2(2)+2+2(0))+2(2+2(0))+2(0),这个过程就是在重复。
设 f(n)就是将 n分解为2的次方和,我们只要确立边界和递归的公式条例就可以了。而在这个问题中是需要打印出一串表达式,直接在递归时打印就可以了,不需要返回值;

可以看到表达式中只有2和0出现。
if(n==1) {System.out.print(“2(0)”);return;} return;这样表示递归中结束又不返回值,很实用
if(n==2) {System.out.print(“2”);return;}
而当n>2时,我们设m为小于等于n的2的最大次数幂,x为那个次数 例如n=10,m=2(3)=8,x=3;
if(n==m) 说明n是一个2的次数幂,就像137=2(7)+2(3)+2(0) 里的2(7),2(3),2(0)
都是递归当中的一个子项,当n等于其中一个时,我们再将x进行重复的操作得到这些子项的子项,,一直到边界条件就可以了,

if(n==m) {//每个子项都是一个闭环2(  .... )
            System.out.print("2(");
            f(x);
            System.out.print(")");
}

而如果n!=m ,就像137=2(7)+2(3)+2(0) 而n=137是由多个 递归子项加和而成的,也分两种情况m!=2

//构成了闭环先将其中一个子项输出,再后面  +  f(n-m)将剩余的数再传入
    System.out.print("2(");
    f(x);
    System.out.print(")+");
    f(n-m);
    //从而构成一整个表达式 如7=2(2)+2+2(0),

而如果m=2说明x=1,即n=3,为什么要分开讨论呢,因为当n太小时,是不用一个闭环来表达的,直接可以分散开,如3=2+2(0):而10=2(2+2(0))+2需要一个闭环。 从测试中发现,当m=2时符合分散条件,无需添加闭环

else {
            if(m==2) {
                System.out.print("2+");//2就是其中子项
                f(n-m);//加上剩余的数 的表达式
            }else {
                System.out.print("2(");
                f(x);
                System.out.print(")+");
                f(n-m);
            }
        }

完整代码如下:

package devide;

import java.util.Scanner;

public class Power2 {

    public static int log2(int n) {
        return (int)((Math.log(n))/(Math.log(2)));
        //用log n/log 2代表  Log2 n
    }


    public static void power(int n) {

        if(n==1) {System.out.print("2(0)");return;}
        if(n==2) {System.out.print("2");return;}
        int x=log2(n);//n之下 2次幂最大整数
        int m=(int)Math.pow(2, x);//为2的x次方 

        if(n==m) {
            System.out.print("2(");
            power(x);
            System.out.print(")");
        }else {
            if(m==2) {
                System.out.print("2+");
                power(n-m);
            }else {
                System.out.print("2(");
                power(x);
                System.out.print(")+");
                power(n-m);
            }
        }
    }

    public static void main(String[]args) {
        int n=0,m=0;
        Scanner in=new Scanner(System.in);
        System.out.println("请输入测试次数和测试数据:");
        m=in.nextInt();
        while(m-->0) {
            n=in.nextInt();
            power(n);
        }   
    }

}

转自2的幂次方表示题解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值