洛谷题单指南-二分查找与二分答案-P1024 [NOIP2001 提高组] 一元三次方程求解

原题链接:https://www.luogu.com.cn/problem/P1024

题意解读:方程在-100~100范围内有三个根,则必然存在两个数l<r,使得f(-100) * f(l)<0,f(l)*f(r)<0,f(r)*f(100)<0

解题思路:

设方程的三个根是x1、x2、x3,l在x1、x2之间,r在x2、x3之间,如图

由于三个跟之间距离>=1,最小是1,所以l、r在枚举的时候递增要小于1,用0.5递增即可

找l的代码片段如下:

double i = -100;
while(i <= 100)
{
    if(f(i) * f(-100) < 0)
    {
        l = i;
        break;
    }
    i += 0.5;
}

找r的代码片段如下:

while(i <= 100)
{
    if(f(i) * f(l) < 0 && f(i) * f(100) < 0)    
    {
        r = i;
        break;
    }
    i += 0.5;
}

然后进行三次实数二分操作,分别在-100~l,l~r,r~100区间内找一个根

二分的判定条件是:

对于左边界l,右边界r,中间值mid

如果f(l) * f(mid) <= 0,表示有根,继续减少r的范围,r=mid

否则表示没有根,提升l的范围,l=mid

100分代码:

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

double a, b, c, d;
double l = -100, r = 100;

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

double bs(double l, double r)
{
    while(r - l > 1e-4)
    {
        double mid = (l + r) / 2;
        if(f(l) * f(mid) <= 0) r = mid;
        else l = mid;
    }
    return r;
}

int main()
{
    cin >> a >> b >> c >> d;
    double i = -100;
    while(i <= 100)
    {
        if(f(i) * f(-100) < 0)
        {
            l = i;
            break;
        }
        i += 0.5;
    }
    while(i <= 100)
    {
        if(f(i) * f(l) < 0 && f(i) * f(100) < 0)
        {
            r = i;
            break;
        }
        i += 0.5;
    }
    double x1 = bs(-100, l);
    double x2 = bs(l, r);
    double x3 = bs(r, 100);
    printf("%.2lf %.2lf %.2lf", x1, x2, x3);

    return 0; 
}

 

posted @   五月江城  阅读(33)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示