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

来源:互联网 发布:unity3d 骨骼动画制作 编辑:程序博客网 时间:2024/05/19 20:42

  算法训练 一元三次方程求解  
时间限制:1.0s   内存限制:256.0MB
      
问题描述
  有形如: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

暴力可以过,但说正解是二分,因为每个根之间绝对值大于1,所以可以通过f[i]*f[i+1]<0枚举得出根所在的区间,在二分得到答案

但每一个区间里,是不能保证单调的,根之间的绝对值大于1,并不能保证极值的位置,所以区间内的单调性是不能保证的,应该数据水。。。毕竟暴力能过。。。。

要注意double存时,和零的比较

#include<bits/stdc++.h>using namespace std;double a,b,c,d;const double eps=1e-4;const double eps1=1e-10;double y(double x){    return a*x*x*x+b*x*x+c*x+d;}double solve(double l,double r,int flog){    double mid,ans;    while(r-l>eps)    {        mid=(l+r)/2;        if(y(mid)<=0)        {            ans=mid;            if(flog)            l=mid;            else            r=mid;        }        else        {            if(flog)            r=mid;            else            l=mid;        }    }    return ans;}int main(){    cin>>a>>b>>c>>d;    double i,ans[10];    int j=0,flog;    for(i=-100;i<100;i+=1)    {        if(y(i)*y(i+1)<=0)        {            if(abs(y(i+1)-0)<=eps1)            {                ans[j++]=i+1;                i+=1.0;                continue;            }            else if(abs(y(i)-0)<=eps1)            {                ans[j++]=i;                continue;            }            else if(y(i+1)>y(i))                flog=1;            else                flog=0;            ans[j++]=solve(i,i+1,flog);        }    }    for(j=0;j<3;j++)    printf("%.2lf%c",ans[j]," \n"[j==2]);    return 0;}



0 0