题目描述:
思路:
二分或套盛金公式或暴力求解
二分:
即通过缩小范围找零点来得出方程的解
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
double a,b,c,d;
double f(double x)
{
return (x*x*x*a+x*x*b+x*c+d);//计算一元三次方程的值
}
int main()
{
double x1,x2,xx;
scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
for(double i=-100;i<=100;i++) {//分别枚举
x1=i;x2=i+1;
if(f(x1)==0)//说明为零,直接输出
printf("%.2lf ",i);
if(f(x1)*f(x2)<0) {//小于零说明有零点,即说明有解。
while(x2-x1>=0.001) {//范围
xx=(x1+x2)/2;//二分
if(f(x1)*f(xx)<=0)//判断零点在x1到xx还是xx到x2
x2=xx;//更新
else
x1=xx;
}
printf("%.2lf ",x1);//输出
}
}
}
盛金公式:
先根据公式求出delta的值,然后根据delta的范围套用不同的公式
#include<cstdio>
#include<cmath>
#include<iostream>
using namespace std;
int main()
{
double a,b,c,d; //定义四个系数
double x;
double x1,x2,x3; //定义三个实根
cin>>a>>b>>c>>d;
double A=b*b-3*a*c; //第一重根判别式
double B=b*c-9*a*d; //第二重根判别式
double C=c*c-3*b*d; //第三重根判别式
double del=B*B-4*A*C; //总判别式
if(A==B&&A==0) //如果A=0且B=0
{
x1=x2=x3=(-1*b/(3*a)); //x1,x2,x3的值相同......
}
else if(del==0) //如果△=0,x2与x3相同......
{
x1=(-1*b/a)+B/A;
x2=x3=-1*B/A/2;
}
else if(del<0) //如果△<0,有三实根......
{
double T=(2*A*b-3*B*a)/(2*A*sqrt(A));
double _xt=acos(T);
double xt=_xt/3;
x1=(-1*b-2*sqrt(A)*cos(xt))/(3*a);
x2=(-1*b+sqrt(A)*(cos(xt)+sqrt(3)*sin(xt)))/(3*a);
x3=(-1*b+sqrt(A)*(cos(xt)-sqrt(3)*sin(xt)))/(3*a);
但因为原题限定条件是三实根,只需要取else if(del<0)部分即可
暴力枚举
超时了,没有优化好。。。
数媒202syh