冲刺阶段:二分Can you solve this equation

回过头来,看这些以前做过的题目,还是能有不少收获。
这个题目,我对最后的收敛条件有些疑惑

一开始打算让l和r收敛,也就是l<= r
这样做也是可以的,但是每次走的步长,需要根据最终精确到的结果来确定。这里要注意精确度依赖于步长,
因此我们要 尽可能的缩小这个eps
这种方法的代码如下:
#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std ;
#define eps 1e-6//这里的取值很关键
#include<cmath>
double cacu(double x)
{
    return 8*x*x*x*x+7*x*x*x+2*x*x+3*x+6;
}

int main(){
    int T ;
    double y ;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lf",&y);
        double l = 0 ;
        double r = 100 ;
        if(y-cacu(r)>eps|| cacu(l)-y>eps||y<0)
        {
            printf("No solution!\n");
            continue;
        }
        double mid ;
        while(l<=r)
        {
            mid=(l+r)/2;
            if(cacu(mid)>y)
            {
                r = mid-eps;
            }else {
                l = mid+eps;
            }
        }
        printf("%.4lf\n",l);
    }
}


另一种就是以最终结果相等不相等进行判断。就是直接while循环里进行结果判断,这样收敛方法如下,相应的mid也就是最终结果:

#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std ;
#define eps 1e-5
#include<cmath>
double cacu(double x)
{
    return 8*x*x*x*x+7*x*x*x+2*x*x+3*x+6;
}

int main(){
    int T ;
    double y ;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lf",&y);
        double l = 0 ;
        double r = 100 ;
        if(y-cacu(r)>eps|| cacu(l)-y>eps||y<0)
        {
            printf("No solution!\n");
            continue;
        }
        double mid  =(l+r)/2;
        while(fabs(cacu(mid)-y)>eps)
        {
            if(cacu(mid)>y)
            {
                r = mid;
            }else {
                l = mid;
            }
            mid =(l+r)/2;
        }
        printf("%.4lf\n",mid);
    }
}
两种方法均可。

猜你喜欢

转载自blog.csdn.net/qq_36616268/article/details/80826642