【CodeVS 1038】一元三次方程

题意

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

分析

分析1

求导后二分单调区间。

分析2

由于要求近似解,所以我们从-100.000到100.000进行枚举,步长为0.001即可。
最后去重输出。

#include 
#include 

#define rep(i,a,b) for (int i=(a);i<=(b);i++)

const double L=-100.000;
const double R=100.000;
const double DEL=0.001;

const double EPS=1e-5;

const int N=262144;

double a,b,c,d;
double ans[N]; int tot;

inline int cmp(double i,double j)
{
    if (fabs(i-j)return 0;
    else if (ireturn -1;
    else return 1;
}

double Calc(double a,double b,double c,double d,double x)
{
    return a*x*x*x+b*x*x+c*x+d;
}

int main(void)
{
    freopen("codevs1038.in","r",stdin);
    freopen("codevs1038.out","w",stdout);

    scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
    for (double x=L;cmp(x,R)<=0;x+=DEL)
    {
        double t=Calc(a,b,c,d,x);
        if (!cmp(t,0)) ans[++tot]=x;
    }

    int cur;
    rep(i,1,tot)
    {
        printf("%0.2lf ",ans[i]);
        cur=i;
        while (cur+1<=tot&&cmp(fabs(ans[i]-ans[cur+1]),1)<0)
            cur++;
        i=cur;
    }
    printf("\n");

    return 0;
}

小结

(1)这类近似解的问题,表现为“精确到几位小数之类的”,通常可以直接枚举答案,转为判定性问题。

你可能感兴趣的:(近似解,数学分析,NOIP,解方程)