第五单元 分治算法
5.1 一元三次方程求解
【问题描述】有形如 ax3+bx2+cx+d=0 这样的一个一元三次方程。给出该方程中各项的系数(a,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在-100 至 100 之间),且根与根之差的绝对值≥1。
要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后 4 位。
【分析】
记方程为 f(x)=0,若存在 2 个数 x1和 x2,且 x1<x2,f(x1)·f(x2)<0,则在(x1,x2)之间一定有一个根。
如果保留小数点后 2 位,则可以从-100.00 到 100.00 进行枚举,步长 0.01,然后取使 f(x)最接近 0的三个数。
当已知区间(a,b)内有一个根时,可用二分法求根。若区间(a,b)内有根,则必有 f(a)·f(b)<0。重复执行如下的过程:
令 m=(a+b)÷2,
(1) 若 a+0.0001>b 或 f(m)=0,则可确定根为 m,并退出过程;
(2) 若 f(a)·f(m)<0,则根在区间(a,m)中,故对区间重复该过程;
(3) 若 f(a)·f(m)>0,则必然有 f(m)·f(b)<0,根在(m,b)中,对此区间重复该过程。
执行完毕,就可以得到精确到 0.0001 的根。
所以,根据“根与根之差的绝对值≥1”,我们先对区间[-100,-99]、[-99,-98]……[99,100]进行枚举,确定这些区间内是否有解,然后对有解的区间使用上面的二分法。这样就能快速地求出所有的解了。
5.2 快速幂
用朴素算法求时间复杂度为 O(n)。能不能更快一些?
以为例。我们知道,求一个数的平方是很快的,因为不用循环。那么