《一元三次方程求解》牛顿迭代解法

一元三次方程求解

http://www.nowcoder.com/questionTerminal/ed2ece368ae94c36968478b6f9ba79c8

这道题的标准解法是使用二分查找,题目给出了如何判定区间内是否有根的提示,即则在之间一定有一个根。

但是如果借助微积分技巧,这道题还可以有另外一种解法。

首先,我们考虑若三次函数区间存在三个实根,那么该函数在该区间内必定存在两个顶点,即其导数在该区间内有两个实根,其中,我们可以使用一元二次方程求根公式分别求出,求根公式为:

根据导数的性质,我们可以确定的三个根分别位于区间内。于是我们可以在这三个区间内分别使用牛顿迭代法进行求根。其中牛顿迭代法公式为:

迭代的初始值可以设定为该区间的中点,一般每个区间两三次迭代即可完成。

代码如下:

#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;

double a, b, c, d;
const double eps = 1e-3;

double f(double x) { //求f(x)的值
    return a * x * x * x + b * x * x + c * x + d;
}

double fp(double x) { //求导数f'(x)的值
    return 3 * a * x * x + 2 * b * x + c;
}

double newton(double x0) { //牛顿迭代,精度为1e-3
    double x = x0;
    do {
        x0 = x;
        x = x0 - f(x0) / fp(x0);
    } while (abs(x - x0) > eps);
    return x;
}

int main() {
    cin >> a >> b >> c >> d;

    //求导数f'(x)的两个根,即函数f(x)的两个顶点
    double delta = sqrt(b * b - 3 * a * c);
    double xp1 = (-b - delta) / (a * 3);
    double xp2 = (-b + delta) / (a * 3);

    //分别对三个区间使用牛顿迭代求根
    double x1 = newton(-100 + (xp1 + 100) / 2);
    double x2 = newton(xp1 + (xp2 - xp1) / 2);
    double x3 = newton(xp2 + (100 - xp2) / 2);

    cout << fixed << setprecision(2) << x1 << " " << x2 << " " << x3;
}
全部评论

相关推荐

03-10 14:19
已编辑
重庆邮电大学 前端工程师
球Offer上岸👑:测试也难求一面 逆天
点赞 评论 收藏
分享
03-29 14:19
门头沟学院 Java
你背过凌晨4点的八股文么:加油同学,人生的容错率很高,只是一个暑期罢了,后面还有很多机会!
点赞 评论 收藏
分享
评论
7
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务