剪绳子,大数取余法

1.题目描述

在这里插入图片描述

2.思路

经过数学推导,当绳子尽可能地剪成长度为3的段的时候,结果最大,因此
1.当n<=3时,返回n-1
2.当余数为0时,返回3^a
3.当余数为1时,返回3^(a-1)4
4.当余数为2时,返回3^a
2

大数求余,第一种时循环求余
在这里插入图片描述
第二种是快速幂求余
对于幂次,分为奇数和偶数两种情况
在这里插入图片描述
可以写出求余数的代码,循环求余法

public long getRemain(int a,int x){
        long rem = 1;
        while (x-->0){
            rem = (rem * a) % 1000000007;
        }
        return rem;
    }

快速幂求余法

public long getRemain(long base, int num){
        long res = 1;
        while (num>=1){
            if ((num&1)==1){
                res = (res * base) % p;
            }
            base = (base * base) % p;
            num >>= 1;
        }
        return res;
    }

3.代码

public class 剪绳子1 {
    public int cuttingRope(int n) {
        if (n<=3) return n-1;
        int a = n / 3;
        int b = n % 3;
        if (b==0) return (int) Math.pow(3,a);
        else if (b==1) return (int) (Math.pow(3,a-1)*4);
        else return (int) (Math.pow(3,a)*2);
    }

    public static void main(String[] args) {
        剪绳子1 x = new 剪绳子1();
        System.out.println(x.cuttingRope(10));
    }
}

这里要注意求余数时base使用long型,因为可能会超出int的范围

public class 剪绳子2 {
    int p = 1000000007;
    public int cuttingRope(int n) {
        if (n<=3) return n-1;
        int a = n / 3;
        int b = n % 3;

        if (b==0) return (int)(getRemain(3,a) % p);
        else if (b==1) return (int) (getRemain(3,a-1)*4 % p);
        else return (int) (getRemain(3,a) * 2 % p);
    }

    public long getRemain(long base, int num){
        long res = 1;
        while (num>=1){
            if ((num&1)==1){
                res = (res * base) % p;
            }
            base = (base * base) % p;
            num >>= 1;
        }
        return res;
    }
}

4.总结

掌握剪绳子的数学推导和大数求余的方法。

5.数值的整数次方

题目描述
在这里插入图片描述
思路:参考大数求余的思路
只不过这里不需要求余数了,直接把幂次的结果返回即可
代码如下:
要注意把n用long表示,因为int32 变量n∈[−2147483648,2147483647],当 n = -2147483648 时执行 n = -n 会因越界而赋值出错。

public class 数值的整数次方 {
    public double myPow(double x, int n) {
        //注意:Java 代码中 int32 变量n∈[−2147483648,2147483647]
        //因此当 n = -2147483648 时执行 n = -n 会因越界而赋值出错
        //我们此处一开始就把 n 用 long 存储
        double res = 1;
        long b = n;
        if (b<0) {
            x = 1/x;
            b = -b;
        }
        while (b>0){
            if ((b&1)==1){
                res = res * x;
            }
            x = x * x;
            b >>= 1;
        }
        return res;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值