一元三次方程求解 (laoj1114)

一元三次方程求解 (laoj1114)
有形如:ax^3+bx^2+cx+d=0这样的一个一元三次方程。给出该方程中各项的系数(a,b,c,d均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与根之差的绝对值>=1。要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后4位。
提示:记方程f(x)=0,若存在2个数x1和x2,且x1 输入格式:输入该方程中各项的系数a,b,c,d
输出格式:由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后2位。
输入示例:1 -5 -4 20
输出示例:-2.00 2.00 5.00

【分析】
如果精确到小数点后两位,可用简单的枚举法:
将x从-100.00到100.00(步长为0.01)逐一枚举,得到20000个f(x),取其值与0最接近的三个f(x),对应的即为答案。
而题目已改成精度为小数点后4位,枚举算法肯定会超时。
直接利用求根公式,极为复杂。
我们想到二分法:利用二分法逐步缩小根的范围,从而得到根的某精度的数值。
当已知区间(a,b)内有一个根时,用二分法求根。
若区间(a,b)内有根,则必有f(a)*f(b)<0。重复执行下面的过程:
(1)若f((a+b)/2)=0或a+0.0001>b ,则可确定根为(a+b)/2并退出过程;
(2)若f(a)*f((a+b)/2)<0,由零点定理可知根在区间(a,(a+b)/2)中,则对区间重复该过程;
(3)若f(a)*f((a+b)/2)>0,则必有f((a+b)/2)*f(b)<0,则根在((a+b)/2,b)中,则对该区间重复该过程。
执行完毕,输出根。

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
double a,b,c,d,ans[3];
int n=0;
double cal(double x){
    return x*x*x*a+x*x*b+x*c+d;
}
void fz(double l,double r){
    if(cal(l)*cal(r)>0&&((r-l)<1||n>=2)) return ;
    double mid=(l+r)/2;
    if(abs(cal(mid))<=1e-5){
            ans[n++]=mid;
            return ;
        }
    fz(l,mid);
    fz(mid,r);
}
int main(){
    cin>>a>>b>>c>>d;
    fz(-100,100);
    printf("%.2f %.2f %.2f",ans[0],ans[1],ans[2]);
    return 0;
} 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值