测评请前往##Luogu##

题目背景

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

题目描述

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

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

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

现给定一个三次线性函数

f(x)=abx3+cdx2+efx+ghf(x) = \frac{a}{b} x^3 + \frac{c}{d} x^2 + \frac{e}{f} x + \frac{g}{h}

求解其在[M,N][M,N]内的零点(保留77位小数)

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

输入输出格式

输入格式

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

输出格式

一个77位小数

输入输出样例

输入样例#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=0a = 0
对于前20%~40%的数据,保证b=d=f=h=1b = d = f = h = 1
对于前100%的数据,保证在[M,N][M,N]内至多有一个零点

PS: float:223=83886082^{23} = 8388608,一共七位,这意味着最多能有77位有效数字,但绝对能保证的为66位,也即float的精度为6677位有效数字;

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;
}