快速幂算法

现在越来越深刻的理解到 算法 = 数学 这个公式了,当兴致勃勃要写一道算法题的时候,经常被数学给难住,代码还没开始编写🤷‍♀️,一大半时间都在思考数学问题😒(ps:笨的人只能靠努力😭了~~花时间了~~)。

今天就以快速幂算法为例,让大家感受一下😏数学之美、算法之美👀。

一、幂运算

快速幂 ,顾名思义就是快速做运算(剩下大把的时间............)。那什么是幂运算呢?

答: 幂(power)是指乘方 运算的结果。n^m指该式意义为m个n相乘 。把n^m看作乘方的结果,叫做n的m次幂 ,也叫n的m次方, 其中,n是底数,m是指数

**举例🎤:**2^3,指的是3个2相乘。因为2^3=8,所以8是乘方的结果,此时称为2的3次幂,也叫做2的3次方🎨。

二、幂的数学表示和规则

为了说清楚快速幂的基本原理 ,此处引入幂在数学中表示方式和运算规则。一般而言,如果你想表示a的b次方,在数学上可以这样写:

比如:想要表示2的3次方5的2次方,可以这样写:

如果做乘法运算的话,有这样一个规则:**底数相同,指数相加,**例子如下:

且有这样以下的式子恒成立

三、快速幂的基本原理

如果我们换一个角度看问题,我们可以将这个数进行这样的拆解:

式子1

如果以上式子理解起来还是有一些困难的话,我们再看看这个式子:这个式子和上面的式子是等价的,运算次数也是4次。

式子2

四、循环求快速幂

**基本思想:**参考式子1,将底数不断变大,指数缩小。

现在需要编写循环代码求解以下式子:

如何将底数不断变大,指数不断缩小求解答案呢?

参考代码如下:

​​​在这里,你们可以将2^6代入到代码中进行模拟 。感受一下循环求解快速幂的过程。

总结:快速幂是一个将底数等价增大,指数等价缩小的过程。

**当指数b是偶数时,**有:

**当指数b是奇数时,**有:

五、递归求快速幂

基本思想: 参考式子2,将大规模问题变成小规模问题🐱‍🏍,从而得出最终的答案。

**比如:**现在要求解2^6🤔的值,那么可以将2^6看成:2^6 = 2^3 * 2^3,这个时候问题规模由2^6变成了2^3,而2^3 = 2^2 * 2^1,此时问题规模由2^3变成了2^2,然后把2^2看成2^2 = 2^1 * 2^1,此时问题规模由2^2变成了2^1,2^1的结果为2,已经知道最小问题规模的答案为2,此时一步一步反推回去,最终能够求出2^6等于64。

参考代码如下:

六、快速幂中的取余运算

在做和快速幂有关的题目的时候,经常会发现有个取余运算,主要原因是因为现在oj网站的题或者竞赛的题,如果a的b次幂且b很大(b很大会爆空间)😑,那么题中大多会让你把结果对一个数取余也就是求模,例如a^b%c这种。

【题目描述】

假设今天是星期日,那么过a的b次方天之后是星期几☕?

【输入】

两个🛒正整数a,b,中间用单个空格隔开。0<a≤100,0<b≤10000。

【输出】

一个字符串😏,代表过a的b次方天之后是星期几

其中,Monday是星期一,Tuesday是星期二,Wednesday是星期三,Thursday是星期四,Friday是星期五,Saturday是星期六,Sunday是星期日。

【输入样例】

3 2000

【输出样例】

Tuesday

数学上有一个公式:(a*b)%m = (a%m * b%m) %m

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int a,b,m=7,res=1;
int main() {
	cin >> a >> b;
	while(b!=0) {
		if(b%2==1) {
			res = res * a % m;
		}
		a = a * a % m;
		b = b/2;
	}
	switch(res) {
		case 0: {
			cout << "Sunday" << endl;
			break;
		}
		case 1: {
			cout << "Monday" << endl;
			break;
		}
		case 2: {
			cout << "Tuesday" << endl;
			break;
		}
		case 3: {
			cout << "Wednesday" << endl;
			break;
		}
		case 4: {
			cout << "Thursday" << endl;
			break;
		}
		case 5: {
			cout << "Friday" << endl;
			break;
		}
		case 6: {
			cout << "Saturday" << endl;
			break;
		}
	}
	return 0;
}

假设今天是周日,以求解 2^3是星期几为例,即求2^3%7的结果 ,通过公式我们知道:

(2 * 2 * 2) % 7 = (2%7 * (2*2)%7) % 7。

接下来,我们对代码进行数据模拟🍭 ,试试看当a=2,b=3时,能否得到以上式子。

第一步:输入a、b,a=2,b=3

第二步:判断b是否为0,b不为0,且b为奇数,得到 res = 2%7

第三步:a的值重新设为 a = (2*2)%7

第四步:b为1,执行 res = (2%7 * (2*2)%7) % 7

第五步:计算a、b,b为0,退出while循环。

通过以上五个步骤的模拟,可以知道,最终res的值和公式求解的值一致😁


七:总结

编写通俗易懂的算法 文章是一件特别有意思、有成就感的事情😁,接下来我将编写各种专题算法😕 ,同时配备视频,有需要的小伙伴可以喊我一声⛳。

相关推荐
ahadee8 小时前
蓝桥杯每日真题 - 第19天
c语言·vscode·算法·蓝桥杯
恃宠而骄的佩奇10 小时前
i春秋-签到题
web安全·网络安全·蓝桥杯
ahadee12 小时前
蓝桥杯每日真题 - 第18天
c语言·vscode·算法·蓝桥杯
St_Ludwig13 小时前
C语言 蓝桥杯某例题解决方案(查找完数)
c语言·c++·后端·算法·游戏·蓝桥杯
BigShark8881 天前
2025蓝桥杯(单片机)备赛--扩展外设之I2C的重要应用--PCF8591(八)
单片机·职场和发展·蓝桥杯
BigShark8881 天前
2025蓝桥杯(单片机)备赛--扩展外设之NE555的使用及定时器1的详细讲解(十)
单片机·职场和发展·蓝桥杯
BigShark8881 天前
2025蓝桥杯(单片机)备赛--扩展外设之DS1302的使用(九)
单片机·职场和发展·蓝桥杯
濊繵2 天前
备赛蓝桥杯--算法题目(1)
算法·职场和发展·蓝桥杯
学习前端的小z2 天前
【蓝桥杯C/C++】深入解析I/O高效性能优化:std::ios::sync_with_stdio(false)
c++·蓝桥杯
漫无目的行走的月亮2 天前
鲸鱼机器人和乐高机器人的比较
少儿编程