洛谷题单指南-二分查找与二分答案-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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?