1.题目描述
2.思路
经过数学推导,当绳子尽可能地剪成长度为3的段的时候,结果最大,因此
1.当n<=3时,返回n-1
2.当余数为0时,返回3^a
3.当余数为1时,返回3^(a-1)4
4.当余数为2时,返回3^a2
大数求余,第一种时循环求余
第二种是快速幂求余
对于幂次,分为奇数和偶数两种情况
可以写出求余数的代码,循环求余法
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;
}
}