洛谷 P1024 一元三次方程求解 二分

大家觉得写还可以,可以点赞、收藏、关注一下吧!
也可以到我的个人博客参观一下,估计近几年都会一直更新!和我做个朋友吧!https://motongxue.cn


😁 P1024 一元三次方程求解

描述

有形如:ax3+bx2+cx+d=0 这样的一个一元三次方程。

给出该方程中各项的系数(a,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与根之差的绝对值>=1。要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后2位。

输入

一行,包含四个实数a,b,c,d,相邻两个数之间用单个空格隔开。

输出

一行,包含三个实数,为该方程的三个实根,按从小到大顺序排列,相邻两个数之间用单个空格隔开,精确到小数点后2位。

样例输入

1.0 -5.0 -4.0 20.0

样例输出

-2.00 2.00 5.00

分析

记方程f(x)=0,若存在2个不同的数x1x2,且f(x1)*f(x2)<0,则在(x1,x2)之间一定有一个根。

当已知区间(a,b)内有一个根时,可用二分法求根。若区间(a,b)内有根,则必有f(a)*f(b)<0。重复执行如下的过程。

m=(a+b)/2

  1. a+0.0001>bf(m)=0,则可以确定根为m,并退出过程;
  2. f(a)*f(m)<0,则必然有f(m)*f(a)<0根在区间(a,m)中,故对区间重复该过程;
  3. f(a)*f(m)>0,则必然有f(m)*f(b)<0,根在区间(m,b)中,对此区间重复该过程。执行完毕,就可以得到精确到0.0001的根。

代码实现

#include<iostream>
#include<cmath>
#include<iomanip>

using namespace std;

long double  a, b, c, d;

long double f(long double x)
{
    return a*x*x*x + b*x*x + c*x + d;
}

long double Calculator(long double low, long double high)//二分
{
    long double middle = (low + high) / 2;
    if (abs(low - high) <= 0.0001)
    {
        return middle;
    }
    if (f(low)*f(middle) < 0)
    {
        return Calculator(low, middle);
    }
    else
    {
        return Calculator(middle, high);
    }
}


int main()
{
    cin >> a >> b >> c >> d;

    long double L1, L2;

    L1 = (-2 * b - sqrt(4 * b*b - 4 * 3 * a*c)) / (2 * 3 * a);//计算极值点
    L2 = (-2 * b + sqrt(4 * b*b - 4 * 3 * a*c)) / (2 * 3 * a);

    cout << fixed << setprecision(2) << Calculator(-100, L1) << " " << Calculator(L1, L2) << " " << Calculator(L2, 100);

}

提交结果

在这里插入图片描述


2020年9月26日更

大家觉得写还可以,可以点赞、收藏、关注一下吧!
也可以到我的个人博客参观一下,估计近几年都会一直更新!和我做个朋友吧!https://motongxue.cn


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值