一元三次方程
Time Limit: 1 Sec Memory Limit: 128 MBDescription
一个关于x的一元三次方程可以化简为ax
3+bx
2+cx+d=0的形式。已知a,b,c,d,且保证该方程存在三个不同实根,它们的范围在-100至100之间,两根之差的绝对值≥1。请求出这三个实根,精确到小数点后2位。
Input
输入一行,为a,b,c,d,均为实数。
Output
由小到大依次输出三个实根,并精确到小数点后2位。
Sample Input
1 -5 -4 20
Sample Output
-2.00 2.00 5.00
这是我寒假时候做的一个比赛题,到现在我才想起来写这个博客,我认为这个比赛的题还不错,难度适宜。
分析:
1、当我拿到这题时,我惊呆了,不知道如何下手。然后发现数据范围蛮小的,就用for循环:i+=0.01.结果出麻烦了,浮点数不能这样去做,因为浮点数加法不是很精确。
比如:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
//freopen("data.txt","r",stdin); //数据 1 -5 -4 20
double a,b,c,d,i;
cin>>a>>b>>c>>d;
for(i=-100.0;i<=100.0;i=i+0.01) //咋不能出结果??而i++就行
if(a*i*i*i+b*i*i+c*i+d==0.0)
cout<<setprecision(2)<<fixed<<i<<' '; //结果-2.00 2.00 5.00
return 0;
}
#include <iostream>
using namespace std;
int main()
{
for(double i=1;i!=10;i+=0.1)
cout<<i<<endl;
return 0;
}
这个程序便成了死循环出不来了,无法停止输出。
2、那么,这题咋做呢?后来有人告诉我一元三次方程有公式。。。。。。我当时郁闷死了!这也行。。。
3、解法便是盛金公式,根据公式写代码就可以了。
LANGUAGE:C++
CODE:
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
int main()
{
freopen("data.txt","r",stdin);
double a,b,c,d,A,B,o,T;
double x1,x2,x3;
cin>>a>>b>>c>>d;
A=b*b-3*a*c;
B=b*c-9*a*d;
T=(2*A*b-3*a*B)/(2*sqrt(A*A*A));
o=acos(T);
x1=(-1*b-2*sqrt(A)*cos(o/3))/(3*a);
x2=(-1*b+sqrt(A)*(cos(o/3)-sqrt(3.0)*sin(o/3)))/(3*a);
x3=(-1*b+sqrt(A)*(cos(o/3)+sqrt(3.0)*sin(o/3)))/(3*a);
cout<<setprecision(2)<<fixed<<x1<<' '<<x2<<' '<<x3;
return 0;
}