洛谷P1024一元三次方程求解
传送门
具体思路:
根据根与根之间的差的绝对值和范围可知,三个数最多分布在 \(200\) 个区间长度为 \(1\) 的区间内。
通过题目给出的条件 \(f(x1)\cdot f(x2)<0\) 找出三个范围,只需暴力枚举 \([-100,100]\) 之间的每一个区间,分别进行二分即可。
细节:注意需要更加小心的处理 \(f(x1)\cdot f(x2)=0\) 的情况
代码
#include<iostream>
#include<cmath>
using namespace std;
const double eps=1e-3;
double a,b,c,d;
double ans[4];
int cnt;
double f(double x)
{
return a*x*x*x+b*x*x+c*x+d;
}
bool check(double l,double r)
{
if(f(l)*f(r)<=0)return 1;
return 0;
}
int main()
{
scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
for(int i=-100;i<100;i++)
{
double l=i,r=i+1;
if(cnt==3)break;
if(!check(l,r))continue;
if(f(l)==0)
{
if(abs(ans[cnt]-l)>=1||!cnt)ans[++cnt]=l;
continue;
}
while(r-l>eps)
{
double mid=(l+r)/2.0;
if(check(l,mid))r=mid;
else l=mid;
}
if(abs(ans[cnt]-l)>=1||!cnt)ans[++cnt]=l;
}
for(int i=1;i<=3;i++)
printf("%.2lf ",ans[i]);
return 0;
}
总结:
充分利用题目信息,走投无路时看看题目还有哪些关键的信息没有使用,在本题中,根的范围在 \(-100\) 至 \(100\) 之间就是一个关键的信息。
针对区间进行二分,前提是区间时具有单调性的,本题需要先找出单调区间才能二分。因此需要考虑的问题是如何找区间,而不是如何二分。