现在越来越深刻的理解到 算法 = 数学 这个公式了,当兴致勃勃要写一道算法题的时候,经常被数学给难住,代码还没开始编写♀️,一大半时间都在思考数学问题(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的b次方天之后是星期几。其中,Monday是星期一,Tuesday是星期二,Wednesday是星期三,Thursday是星期四,Friday是星期五,Saturday是星期六,Sunday是星期日。
【输入样例】
3 2000【输出样例】
Tuesday
数学上有一个公式:(a*b)%m = (a%m * b%m) %m
#include
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的值和公式求解的值一致。
编写通俗易懂的算法文章是一件特别有意思、有成就感的事情,接下来我将编写各种专题算法,同时配备视频,有需要的小伙伴可以喊我一声⛳。