2500: 【普及-】【P1024】一元三次方程求解

内存限制:128 MB 时间限制:1.000 S
评测方式:文本比较 命题人:
提交:1 解决:1

题目描述

有形如:lns="http://www.w3.org/1998/Math/MathML">3+2++=0 这样的一个一元三次方程。给出该方程中各项的系数(lns="http://www.w3.org/1998/Math/MathML">,,, 均为实数),并约定该方程存在三个不同实根(根的范围在 lns="http://www.w3.org/1998/Math/MathML">100 至 lns="http://www.w3.org/1998/Math/MathML">100 之间),且根与根之差的绝对值 lns="http://www.w3.org/1998/Math/MathML">1。要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后 lns="http://www.w3.org/1998/Math/MathML">2 位。

提示:记方程 lns="http://www.w3.org/1998/Math/MathML">()=0,若存在 lns="http://www.w3.org/1998/Math/MathML">2 个数 lns="http://www.w3.org/1998/Math/MathML">1 和 lns="http://www.w3.org/1998/Math/MathML">2,且 lns="http://www.w3.org/1998/Math/MathML">1<2lns="http://www.w3.org/1998/Math/MathML">(1)×(2)<0,则在 lns="http://www.w3.org/1998/Math/MathML">(1,2) 之间一定有一个根。

输入

一行,lns="http://www.w3.org/1998/Math/MathML">4 个实数 lns="http://www.w3.org/1998/Math/MathML">,,,

输出

一行,lns="http://www.w3.org/1998/Math/MathML">3 个实根,从小到大输出,并精确到小数点后 lns="http://www.w3.org/1998/Math/MathML">2 位。

样例输入 复制

1 -5 -4 20

样例输出 复制

-2.00 2.00 5.00

提示

#include<bits/stdc++.h>
using namespace std;
#define eps 1e-4
double A,B,C,D;
double f(double x) {
	return A*x*x*x+B*x*x+C*x+D; 
}
int main(){
	cin>>A>>B>>C>>D;
    for (int i = -100; i <= 100; i++) {
        double L = i, R = i + 1, mid; //这里只处理区间[L,R)上的根
        if (fabs(f(L)) < eps)//如果L是根,可以直接输出
            printf("%.2lf ", L);
        else if (fabs(f(R)) < eps)//如果R是根,跳过
            continue;
        else if (f(L) * f(R) < 0) {//在(L,R)上有根,执行二分
            while (R - L > eps) {
                mid = (L + R) / 2;
                if (f(mid) * f(R) > 0)
                    R = mid;//如果f(mid)和f(R)正负性相同,那么零点在mid左侧
                else
                    L = mid;//否则在另一侧
            }
            printf("%.2lf ", L);
        }
    }
	return 0;
}