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

时间:2024-06-17 20:37:19

一元三次方程求解

描述

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

格式

输入格式

输入该方程中各项的系数(a,b,c,d 均为实数),

输出格式

由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后2位。

样例1

样例输入1

1 -5 -4 20

样例输出1

-2.00 2.00 5.00

限制

每个测试点1s

提示

提示:记函数f(x),若存在2个实数x1和x2,且x1<x2,使f(x1)*(x2)<0,则在(x1, x2)之间一定存在实数x0使得f(x0)=0。

来源

NOIP2001第一题

题目链接:https://vijos.org/p/1116

分析:又来一道暴力题,听说这是一道很经典的二分?贴个二分的代码啊,暴力肯定可以,但是但是,一定要注意精度QAQ

暴力代码:【一个三元函数的性质,不懂的自己翻高中课本】

 #include <bits/stdc++.h>
using namespace std;
int main()
{
double a,b,c,d;
cin>>a>>b>>c>>d;
double j=-;
double i=j;
for(j;j<=;j+=0.01)
{
if(a*i*i*i+b*i*i+c*i+d<)
{
if(a*j*j*j+b*j*j+c*j+d>)
{
printf("%.2lf ",j);
i=j;
}
}
if(a*i*i*i+b*i*i+c*i+d>)
{
if(a*j*j*j+b*j*j+c*j+d<)
{
printf("%.2lf ",j);
i=j;
}
}
}
printf("\n");
return ;
}

直接贴了二分代码:

 #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iomanip>
#include <cstdlib>
using namespace std; float ans[];
float a,b,c,d;
int n=; float f(float x)
{
return ((a*x+b)*x+c)*x+d;
} void solve(float l,float r)
{
if(f(l)*f(r)>&&(((r-l)<)||n>=))
return;
float mid=(l+r)/; if(f(mid)<=1e- && f(mid)>=-1e-)
{
ans[n++]=mid;
return;
} solve(l,mid),solve(mid,r);
} int main()
{
cin>>a>>b>>c>>d;
solve(-,);
printf("%.2lf %.2lf %.2lf",ans[],ans[],ans[]);
return ;
}