P1024 [NOIP2001 提高组] 一元三次方程求解

题目描述
有形如:a x^3 + b x^2 + c x + d = 0ax
3
+bx
2
+cx+d=0 这样的一个一元三次方程。给出该方程中各项的系数(a,b,c,da,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在 -100−100 至 100100 之间),且根与根之差的绝对值 \ge 1≥1。要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后 22 位。

提示:记方程 f(x) = 0f(x)=0,若存在 22 个数 x_1x
1

和 x_2x
2

,且 x_1 < x_2x
1

2

,f(x_1) \times f(x_2) < 0f(x
1

)×f(x
2

)<0,则在 (x_1, x_2)(x
1

,x
2

) 之间一定有一个根。

#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
int main(){
     double a , b , c , d;
     double e , f , g , h;
     double num1,num2,num3;
     cin >> a >> b >> c >> d;
     e = b * b - 3 * a * c;
     f = b * c - 9 * a * d;
     g = (2 * e * b - 3 * a * f) / (2 * sqrt(e * e * e));
     h = acos(g);
     num1 = (-b - 2 * sqrt(e) * cos(h / 3))/(3 * a);
     num2 = (-b + sqrt(e) * (cos(h / 3)+sqrt(3) * sin(h/3))) / (3 * a);
     num3 = (-b + sqrt(e) * (cos(h/3) - sqrt(3) * sin(h/3))) / (3 * a);
     cout << fixed << setprecision(2) << num1 << " ";
     cout << fixed << setprecision(2) <<num3 << " ";
     cout << fixed << setprecision(2) <<num2 << " ";
     return 0;
}