【codevs1038 一元三次方程求解】分治

来源:互联网 发布:淘宝卖家在哪里拿货 编辑:程序博客网 时间:2024/06/06 11:48

这道题WA了将近两天!!!!!我最近一写题就WA,一WA就一天!!!!简直有毒。

题目里说了根的范围是(100,100) ,而且根与根之差的绝对值>=1,那么思想就是把(100,100) 分成[100,99] [99,98] ……这样一个一个的区间,看看区间端点a、b,f(a) * f(b)是否<0,是的话就对这个区间二分,找出答案。

这道题不能直接二分,因为它不是一个单调区间。超超超超超级棒的ilern跟我说如果是单调区间就可以直接二分,如果不是的话就把它划分成几个单调区间来二分。

知道了思想之后还是WA,原因是double用的不熟练。
double类型,输入用%lf, 输出是%.2lf, 2是要求保留2位小数。
float用%f输入,%.2f输出。
printf(“%03d”, 25)的结果是025%3d的结果是25。就可以控制输出的格式。

需要注意的是用double需要注意精度,比较和常数的大小啊啥的都要允许有误差。可以定义 const double EPS = 1e-7;

#include <cstdio>#include <cmath>const double EPS = 1e-7;double a, b, c, d, x1, x2, x3, l[4], r[4];double f(double x){    return a * x * x * x + b * x * x + c * x + d;}double find(double l, double r){    //printf("find(%lf, %lf)\n", l, r);    if (fabs(l - r) <= EPS || fabs(f((l + r) / 2)) <= EPS)    {        return (l + r) / 2;    }    else    {        if (f(l) * f((l + r) / 2) <= EPS)        {            return find(l, (l + r) / 2);        }        else        {            return find((l + r) / 2, r);        }    }}bool have(double a, double b){    //double fa = f(a), fb = f(b);    //printf("f(a = %.3lf) = %.3lf, f(b = %.3lf) = %.3lf\n", a, fa, b, fb);    if (f(a) * f(b) <= EPS)    {        return true;    }    else    {        return false;    }}int main(){    scanf("%lf %lf %lf %lf", &a, &b, &c, &d);    int cnt = 0;    for (int i = -100; i < 100; i++)    {        double j = i + 1 - EPS;        if (have(i, j) == true)        {            l[cnt] = i;            r[cnt] = j;            cnt++;        }    }    x1 = find(l[0], r[0]);    x2 = find(l[1], r[1]);    x3 = find(l[2], r[2]);    printf("%.2lf %.2lf %.2lf\n", x1, x2, x3);    return 0;}

第一种。。。。。。我自己的bug找不出来,然后很表脸的去找了【dalao】debug,然后输出中间变量的调试方法get√【最近用gdb就只会设断点,跑跑跑,都不会输出中间变量了= =】
有的时候要加fabs【实数去绝对值,整数是abs】【例如f(d) == 0就要改成fabs(f(d)) <= EPS】,但是有的时候不用加。

#include <cstdio>#include <cmath>const double EPS = 1e-7;double a, b, c, d, x1, x2, x3;double f(double x){    return a * x * x * x + b * x * x + c * x + d;}bool have(double a, double b){    // double fa = f(a), fb = f(b);    // printf("f(a = %.3lf) = %.3lf, f(b = %.3lf) = %.3lf\n", a, fa, b, fb);    if (f(a) * f(b) <= EPS)    {        return true;    }    else    {        return false;    }}void find(double l, double r){    //printf("find(%lf, %lf)\n", l, r);    double d = (l + r) / 2;    if ((r - l) <= EPS || fabs(f(d)) <= EPS)    {        printf("%.2lf ", d);        return;    }    else    {        if (f(l) * f(d) <= EPS)        {            find(l, d);        }        else        {            find(d, r);        }    }}int main(){    scanf("%lf %lf %lf %lf", &a, &b, &c, &d);    for (int i = -100; i < 100; i++)    {        if (have(i, i + 1 - EPS) == true)        {            find(i, i + 1 - EPS);            //printf("%d\n", i);        }        else continue;    }    return 0;}

第二种。。。。。。【然而并没有太大的差别(:з」∠)
这个WA了很久的原因是主函数里i在循环的时候如果解是整数,就当i= i和i+ 1的时候都符合have,它都会输出。然后把边界定成(i, i + 1 - EPS)就行了。

【我还是太差了,这道并不算很难的题写了好久,有的bug自己还看不出来qnq】

0 0
原创粉丝点击