总时间限制: 1000ms 内存限制: 65536kB

描述

求下面方程的根:

POJ 4140 方程求根 - 图1%20%3D%20x%5E3-%205x%5E2%2B%2010x%20-%2080%20%3D%200%0A#card=math&code=f%28x%29%20%3D%20x%5E3-%205x%5E2%2B%2010x%20-%2080%20%3D%200%0A)

输入

输出

精确到小数点后9位。

样例输出

  1. 5.705085930

思路

f(x) 求导, 得到 f’(x) = 3x-10x+10. 为了判断 f’(x) 的正负性, 我们令 f’(x) = 0, 得到 3x-10x+10 = 0. 经计算可知, 该方程无解.

因此, f’(x) 恒大于0, 故 f(x) 是单调递增的.

计算可知:

  • POJ 4140 方程求根 - 图2%20%3D%20-80%20%3C%200#card=math&code=f%280%29%20%3D%20-80%20%3C%200)
  • POJ 4140 方程求根 - 图3%20%3D%20520%20%3E%200#card=math&code=f%2810%29%20%3D%20520%20%3E%200)

所以在区间 [0, 10] 之间必然有一根.

我们用二分查找, 一步步逼近题目要求的范围.

代码

  1. #include <iostream>
  2. #include <cmath>
  3. using namespace std;
  4. #define EPS 1e-8
  5. double f(double x) {
  6. return x*x*x - 5*x*x + 10*x - 80;
  7. }
  8. int main() {
  9. double root, x1 = 0, x2 = 10;
  10. root = x1 + (x2 - x1) / 2;
  11. double y = f(root);
  12. while( fabs(y) > EPS ) {
  13. if(y > 0) x2 = root; // 修改右边界
  14. else x1 = root; // 修改左边界
  15. root = x1 + (x2 - x1) / 2; // 修改中点
  16. y = f(root);
  17. }
  18. printf("%.9f\n", root);
  19. return 0;
  20. }