测评请前往##Luogu##

题目背景

二分法求解函数零点有着很多应用价值。

题目描述

给定精确度$ξ$,用二分法求函数$f(x)$零点近似值的步骤如下:

  • 确定区间$[a,b]$,验证$f(a)·f(b) \lt 0$。
  • 求区间$(a,b)$的中点$c$.
  • 计算$f(c)$.
  1. 若$f(c)=0$,则c就是函数的零点;
  2. 若$f(a)·f(c) \lt 0$,则令$b=c$;
  3. 若$f(c)·f(b) \lt 0$,则令$a=c$;
  4. 判断是否达到精确度$ξ$:即若$|a-b| \lt ξ$,则得到零点近似值$a$(或$b$),否则重复2-4.

PS:输出时使用$a$作为近似值

现给定一个三次线性函数
$$f(x) = \frac{a}{b} x^3 + \frac{c}{d} x^2 + \frac{e}{f} x + \frac{g}{h}$$
求解其在$[M,N]$内的零点(保留$7$位小数)

如果函数错误或者无零点请输出 orz

输入输出格式

输入格式

一行共$10$个整数,表示描述中的$a,b,c,d,e,f,g,h,M,N$

输出格式

一个$7$位小数

输入输出样例

输入样例#1:

-3 1 1 1 -1 1 1 1 0 1

输出样例#1:

0.6350242

输入样例#2:

-1 50 5 8998988 -1 1 256666 1 0 100000000

输出样例#2:

234.0529191

说明

数据说明

对于前20%的数据,保证$a = 0$
对于前20%~40%的数据,保证$b = d = f = h = 1$
对于前100%的数据,保证在$[M,N]$内至多有一个零点

PS: float:$2^{23} = 8388608$,一共七位,这意味着最多能有$7$位有效数字,但绝对能保证的为$6$位,也即float的精度为$6$至$7$位有效数字;

PSS:世界上最宽广的是double,比double更高远的是long double

标程

标程#1 - CHY

#include <bits/stdc++.h>
using namespace std;

//谨记使用long double
//本题特殊设计
//orz           20
//float         40
//double        80
//long double   100

long long a, b, c, d, e, f, g, h;
long double A, B, C, D, K, M, N;
bool wrong = false;

void getdata()
{
    cin >> a >> b >> c >> d >> e >> f >> g >> h >> M >> N;
    if (b * d * f * h == 0) //判断函数是否错误
    {
        wrong = true;
        return;
    }
    A = (double)a / b;
    B = (double)c / d;
    C = (double)e / f;
    D = (double)g / h;
}

long double fun(long double x) //定义计算用方程
{
    return A * x * x * x + B * x * x + C * x + D;
}

long double work()
{
    long double a, b, c;
    if (fun(M) == 0.0)  //判断边界零点
        return M;
    else if (fun(N) == 0.0)
        return N;
    a = fun(M);
    b = fun(N);
    if (a * b > 0)  //无零点
    {
        wrong = true;
        return 0;
    }
    while (abs(M - N) > 0.000000001) //精度设置超过2位以防止四舍五入的错误
    {
        K = (M + N) / 2;    //定义域二分
        a = fun(M);
        b = fun(N);
        c = fun(K);
        if (c == 0.0)   //二分处零点
            return K;
        if (a * c < 0)
            N = K;
        else
            M = K;
    }
    return M;
}

int main()
{
    getdata();
    long double ans = work();
    if (wrong)
    {
        cout << "orz" << endl;
        return 0;
    }
    cout << fixed << setprecision(7) << ans << endl;    //四舍五入精度为7位
    return 0;
}