洛谷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\) 之间就是一个关键的信息。

针对区间进行二分,前提是区间时具有单调性的,本题需要先找出单调区间才能二分。因此需要考虑的问题是如何找区间,而不是如何二分。

posted @ 2023-05-25 16:06  week_end  阅读(18)  评论(0编辑  收藏  举报