有函数:(f(x) = x^3 + 6.375 imes x^2 + 3 imes x - 26)
已知 (f(1.0) lt 0, f(2.0) gt 0) 且方程 (f(x) = 0) 在区间 ([1.0, 2.0]) 有且只有一个根,请用二分法求出该根。
输入格式
无。
输出格式
输出该方程在区间 ([1.0, 2.0]) 中的根。要求四舍五入到小数点后 (3) 位。
样例输入
无。
样例输出
不提供。
题目分析
本题涉及算法:二分。
我们之前都使用的是整数的二分,而这道题目使用的是实数之间的二分,所以在细节处理中和整数的二分稍有区别,但是万变不离其宗,我们只需要知道了这道题目的二分思想,那么解决这道题目就会变的很轻松。
题目已经告诉我们 (f(1.0) lt 0 , f(2,0) gt 0) ,而我们的函数图像是连续的,所以在区间 ([1.0 , 2.0]) 之间一定存在一个可行的解 (x_0) 满足 (f(x_0) = 0) ,然后我们就可以二分了。
我们一开始令 (L = 1.0) ,令 (R = 2.0) (注意这里的 (L) 和 (R) 都是实数)。
然后我们循环到 (R - L lt 10^{-5}) 在这种情况下我们能够保证循环结束时的 (L) 和 (R) 保留三位小数的结果是相同的。
然后我们每次取 (mid = (L+R)/2) ,会有两种情况:
- 情况1:(f(mid) gt 0) ,这种情况下说明答案在 区间 ([mid, R]) 中,所以我们令 (L = mid);
- 情况2:(f(mid) le 0) ,其实在 (f(mid) = 0) 时我们是直接可以退出循环了,但是为了和情况1进行相同的处理,我们令 (R= mid) 。
这样循环处理,我们能保证循环结束时 (L) 和 (R) 的前 (4) 位小数相差不超过 (10^{-5}),那么这个时候选择 (L) 或者 (R) 并保留两位有效数组的结果就是我们的答案。
实现代码如下:
#include <bits/stdc++.h>
using namespace std;
double f(double x) {
return x*x*x + 6.375*x*x + 3.0*x - 26.0;
}
int main() {
double L = 1.0, R = 2.0;
while (R - L >= 1e-5) { // 1e-4是科学计数法,表示1乘10的-4次方
double mid = (L + R) / 2.0;
if (f(mid) > 0.0) R = mid;
else L = mid;
}
printf("%.3lf
", R); // 因为R-L<=1e-4,所以这个时候输出L和R都一样
return 0;
}