1238:一元三次方程求解

【原始题目】

1238:一元三次方程求解

时间限制: 1000 ms         内存限制: 65536 KB
提交数: 4113     通过数: 2017
【题目描述】
形如:ax3+bx2+cx+d=0ax3+bx2+cx+d=0 这样的一个一元三次方程。

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

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

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

【输入样例】
1.0 -5.0 -4.0 20.0
【输出样例】
-2.00 2.00 5.00

1238:一元三次方程求解

【分析】

   依次搜索根的范围,找出三个根就OK。原理(连续函数零点存在定理):对于继续函数y=f(x),若f(a)*f(b)<0,则函数在区间(a,b)上必存在零点,那我们的任务就是找到两端点值异号的区间。由于两根差的经验值大于等于1,所以,我们逐个扫描整点函数值的符号就必有线索。(为了防止漏网之鱼,我把扫描间隔改为0.5)。找到范围再定位根,那就简单了——二分法。若f(a)*f(b)<0,取m=(a+b)/2,求f(m)的值。三种情况:1、运气比较好,f(m)=0,那就不用继续了,直接得结果。2、f(m)*f(a)>0,则f(m)*f(b)<0,把根的范围缩小到(m,b),继续递归,在(m,b)中找根。3、f(a)*f(m)<0,说明(a,m)内有根,同2,递归在(a,m)找根。

注意:由于精度原因,符号的判定一般用把x>0改为x>1e-12,x<0改为x<-1e-12(也可以写-x>1e-12),其他情况视为x=0。这个问题在1058题中有说明。

AC代码:

//1238:一元三次方程求解
#include<iostream>
#include<iomanip>
using namespace std;
int k;
double ans[3],a,b,c,d,x0=-101;
//x0是根所在区间的左界,根有可能是-100,所以x0必须小于-100
int f(double x)
{
    double y;
    y=a*x+b;
    y=x*y+c;
    y=x*y+d;//写的有点复杂,顺便搞下秦九韶算法
    if(-y>1e-12)return -1;
    else if(y>1e-12)return 1;
    else return 0;
}

//二分法找根,原理:连续函数y=f(x):f(a)*f(b)<0 ,则在(a,b)上必有一根
double key(double x,double y)
{
    double m=(x+y)/2;
    if(y-x<0.0005||f(m)==0)return m;//精确到小数点后2位,最少多算一位,再送一次精度更高哈
    if(f(x)*f(m)==1)return key(m,y);
    else return key(x,m);
}
int main(){
    cin>>a>>b>>c>>d;
    for(double i=-100;i<=100;i+=0.5)
        if(f(i)==0)
        {
            ans[k++]=i;
            x0=i+0.5;//很重要,否则下次判断符号就错了
            if(k==3)break;
        }
        else if(f(x0)*f(i)==1)x0=i;
        else
        {
            ans[k++]=key(x0,i);
            x0=i;//很重要,否则下次判断符号就错了
            if(k==3)break;
        }
    for(int i=0;i<3;i++)
    cout<<fixed<<setprecision(2)<<ans[i]<<‘ ‘;
    return 0;
}

原文地址:https://www.cnblogs.com/wendcn/p/12576231.html

时间: 2024-08-06 11:17:15

1238:一元三次方程求解的相关文章

NOIP2001 一元三次方程求解

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

Vijos P1116 一元三次方程求解【多解,暴力,二分】

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

一元三次方程求解(折半查找)

Description 有形如:ax3+bx2+cx+d=0  这样的一个一元三次方程.给出该方程中各项的系数(a,b,c,d  均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与根之差的绝对值>=1.请你求出这个方程的三个实根. Input 只有一行,包括4个实数a,b,c,d,中间用一个或多个空格隔开. Output 只有一行,包括三个整数,为由小到大排列的三个实根(根与根之间留有空格),并精确到小数点后2位. Sample Input 1   -5   -4

[NOIP提高&amp;洛谷P1024]一元三次方程求解 题解(二分答案)

[NOIP提高&洛谷P1024]一元三次方程求解 Description 有形如:ax3+bx2+cx+d=0 这样的一个一元三次方程.给出该方程中各项的系数(a,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与根之差的绝对值>=1.要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后2位. 提示:记方程f(x)=0,若存在2个数x1和x2,且x1<x2,f(x1)*f(x2)<0,则在(x1,x2)之间一定

算法训练——一元三次方程求解

//一元三次方程求解 //直接枚举 #include<stdio.h> #include<math.h> double a,b,c,d,x; double f(double x){ return a*x*x*x + b*x*x + c*x + d; } int main(){ scanf("%lf%lf%lf%lf",&a,&b,&c,&d); for(x=-100;x<=100;++x){ double z = x,y =

一元三次方程求解

问题描述 有形如:ax3+bx2+cx+d=0 这样的一个一元三次方程.给出该方程中各项的系数(a,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与根之差的绝对值>=1.要求三个实根.. 输入格式 四个实数:a,b,c,d 输出格式 由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后2位 样例输入 1 -5 -4 20 样例输出 -2.00 2.00 5.00 数据规模和约定 |a|,|b|,|c|,|d|<=10 100.

【CodeVS】p1038 一元三次方程求解

题目描述 Description 有形如:ax3+bx2+cx+d=0  这样的一个一元三次方程.给出该方程中各项的系数(a,b,c,d  均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与根之差的绝对值>=1.要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后2位.提示:记方程f(x)=0,若存在2个数x1和x2,且x1<x2,f(x1)*f(x2)<0,则在(x1,x2)之间一定有一个 根. 输入描述 Input Descr

二分查找(vijos1116一元三次方程求解NOIP2001第一题)

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

NOIP2001 一元三次方程求解[导数+牛顿迭代法]

题目描述 有形如:ax3+bx2+cx+d=0 这样的一个一元三次方程.给出该方程中各项的系数(a,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与根之差的绝对值>=1.要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后2位. 提示:记方程f(x)=0,若存在2个数x1和x2,且x1<x2,f(x1)*f(x2)<0,则在(x1,x2)之间一定有一个根. 输入输出格式 输入格式: 一行,4个实数A,B,C,D. 输