快速幂(非递归)

简介: 快速幂(非递归)

题目

已知今天是星期六,请问20^22天后是星期几?

注意用数字1到7表示星期一到星期日。

常规思路(非比赛时使用)

如果大家用java写算法的话,我们知道有这么一个数学类的函数Math.pow(a, b);它能计算a的b次方,并以double类型返回结果,此时我们只需要用得到的结果取模7即可,

代码如下(Java):

public class Main{
   public static void main(String[] args) {
       double pow = Math.pow(20, 22);
        int v = (int) pow % 7;
        System.out.println(v + 6);
    }
}

虽然这样也能做,但是还有更优解,我们利用二进制来优化题解。

快速幂解题(比赛推荐)

解题思路:快速幂的思想:

①把指数想象成二进制的表示方式;

②如果指数不等于0,则判断最后一位是否为1(&),如果是,则用结果变量result 乘 底数 并取模(根据题意设定模的大小),否则不能乘,因为0 * result = 0;

③每进行一次,底数 = 底数 * 底数 % 模 (将指数表示为二进制之后,底数应该对应每次的指数),

即 a的1次 a的2次 a的4次 a的8次 (同底数相乘,指数相加,正好对应二进制的每一位),

例如:20的3次方(3的二进制为11)= 20的(2的1次方)次方 * 20的(2的0次方)次方;

④将指数往右边移动一位,方便进行下一次的判断

⑤其实到这里,快速幂的思想分析已然结束,但是格外的取模操作让人感到不太理解(不考虑数据溢出的情况下可以不取模),为什么每次都可以取模?其实只要是乘法,不论何时取模都是一样的,可以参考 以下公式:

例如:(a * b)% c = (a % c) * (b % c); --> (5 * 6) % 4 = ( 5 % 4) * (6 % 4) = 2

代码如下(Java):

import java.io.*;
public class Main {
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    static int mod = 7;
    public static void main(String[] args) throws IOException {
        bw.write(String.valueOf(FastPower(20, 22) + 6));
        bw.flush();
        bw.close();
    }
    public static int FastPower(int a, int b) {
    int res = 1;
    while (b != 0) {
        if ((b & 1) == 1) {//如果满足条件,则相乘
            res = res * a % mod;
        }
        //无论如何,a都要不断倍增,b都要不断右移
        a *= a % mod;
        b = b >> 1;
    }
    return res;
}

总结

快速幂是经典的数论题目,通过二进制和取模的方式,极大的简化了计算!

文章粗浅,希望对大家有帮助!

相关文章
|
5月前
|
算法 C++
C++快速幂(递归)
C++快速幂(递归)
|
2月前
|
存储 搜索推荐
【非递归版】快速排序算法(4)
【非递归版】快速排序算法(4)
18 0
|
9月前
递归和非递归分别实现求第n个斐波那契数
递归和非递归分别实现求第n个斐波那契数
42 0
|
9月前
快速幂问题
快速幂问题
|
9月前
|
物联网
快速幂
快速幂
57 0
|
机器学习/深度学习
递归实现 八皇后问题(*)
递归实现 八皇后问题(*)
105 0
递归实现 八皇后问题(*)
|
11月前
|
算法
2-路归并排序的递归实现和非递归实现
2-路归并排序的递归实现和非递归实现
|
算法 程序员
双指针算法模板及练习
双指针算法模板及练习
56 1
|
C++
C++解决汉诺塔问题(递归实现)
C++解决汉诺塔问题(递归实现)
362 0
C++解决汉诺塔问题(递归实现)