AcWing 790. 数的三次方根——算法基础课题解
内容提要
给定一个浮点数n,使用二分法求它的三次方根,保留6位小数。
延伸解读
精度选择:为什么用1e-8而不是1e-7
文章指出,保留6位小数时,二分终止条件设为(r-l)>1e-8是为了确保第七位小数准确。若用1e-7,四舍五入可能影响第七位,进而导致输出六位时误差积累。例如实际结果0.1234564555,精确到7位后为0.1234565,再保留六位会进位成0.123457;而精确到8位后为0.12345646,保留六位则正确输出0.123456。因此,1e-8能避免第七位被错误进位。
初始区间[-22,22]的合理性
题目数据范围是-10000≤n≤10000,三次方根的最大绝对值是10000的三次方根,约为21.544,因此初始二分区间取[-22,22]可以覆盖所有可能的解。这个区间略大于实际范围,确保二分查找不会遗漏边界情况。文章中的C和Go代码都使用了这个区间,体现了对数据范围的合理估计。
二分法求三次方根的单调性依据
函数f(x)=x^3在实数域上单调递增,因此对于给定的n,方程x^3=n有唯一实根。二分法利用这一单调性:若mid^3≥n,则根在[l,mid];否则在[mid,r]。通过不断缩小区间,最终逼近精确解。文章中的检查条件正是基于此,保证了二分搜索的正确性。
浮点数二分的通用模板与注意事项
文章给出了浮点数二分的通用模板,其中eps表示精度要求,通常比题目要求多两位。模板结构包括检查函数check和二分搜索函数bsearch_3。使用时需根据具体问题定义check,并设置合适的eps。注意,浮点数二分中循环条件用(r-l)>eps,而非整数二分的l<r,且更新时直接令l=mid或r=mid,无需加减1。
Q&A
如何使用二分法求浮点数的三次方根?
使用二分法时,初始区间为[-22, 22],循环条件为(r - l) > 1e-8,逐步缩小区间直到找到三次方根。
为什么要使用1e-8作为循环条件?
使用1e-8是为了避免因四舍五入导致的误差,确保第七位数字准确,从而正确保留六位小数。
输入浮点数的范围是什么?
输入浮点数的范围为−10000≤n≤10000。
输出结果的格式是什么?
输出结果为一个浮点数,保留6位小数。
能否提供C语言的实现代码示例?
可以,C语言实现代码如下: ```c #include <iostream> using namespace std; int main() { double x; cin >> x; double l = -22, r = 22; while ((r - l) > 1e-8) { double mid = (l + r) / 2; if (mid * mid * mid >= x) r = mid; else l = mid; } printf("%.6lf", l); return 0; } ```
如何确保输出的六位小数是准确的?
确保输出的六位小数准确,需要保证第七位数字不被进位,这样才能避免误差。