一元三次方程式の解(二分法)

1831 ワード

リンク:https://ac.nowcoder.com/acm/problem/16694出典:牛客網
タイトルの説明
有形は、ax 3+bx 2+cx+d=0のような一元三次方程式である.この方程式の各係数(a,b,c,dはいずれも実数)を与え,この方程式には3つの異なる実根(根の範囲は−100〜100の間)が存在し,根と根の差の絶対値≧1があることを約束した.この3つの実ルート(ルートとルートの間にスペースが残っている)を小さいから大きいまで順次同じ行に出力し、小数点以下2桁まで正確にする必要があります.ヒント:方程式f(x)=0を記し、2つの数x 1とx 2が存在し、x 1説明を入力:
  ,4   A,B,C,D。

出力の説明:
  ,3   ,        2 。

例1
入力
コピー1-5-4 20
1 -5 -4 20

しゅつりょく
コピー-2.00 2.00 5.00
-2.00 2.00 5.00

具体的には二分法の基本思想を参考にすることができ、テーマによって根の範囲は-100~100であることがわかり、私たちは1つの整数区間で根の近似値を探すことができ、根がちょうど整数であれば、直接出力することができ、小数であれば一歩一歩近づく必要がある.計算の重複を防ぐことにも注意してください.
#include "bits/stdc++.h"
typedef long long int ll;
using namespace std;
double a,b,c,d;
double def(double x)
{
    double y=((a*x+b)*x+c)*x+d; //     
    return y;
}
int main()
{

    cin>>a>>b>>c>>d;
    for(double i=-100;i<=100;i++)
    {
        double f1=def(i);
        double f2=def(i+1);
        if(f1*f2<=0){
            if(f1==0)
                printf("%.2f ",i);
            else if(f2==0)
            {
                 printf("%.2f ",i+1);
                 i++;   //      
            }
            else
            {
                double l=i,r=i+1;
                double mid;
                //          ,   0.001  
                while(r-l>1e-3){
                    mid=l+(r-l)/2.0;

                    //      
                    if(def(l)*def(mid)<=0)
                        r=mid;
                    else
                        l=mid;
                }
                 printf("%.2f ",mid);
            }
        }
    }
   return 0;
}