五次多项式无求根公式,用题面给出的异号端点与区间内唯一根作前提,实数二分 40 轮后输出中点。
OJ: roj
题目 ID: 1241
难度:普及-
标签:数学二分浮点数python
创建: 2026-09-30 01:19
更新: 2026-10-05 06:30
题目描述
有函数
输入:无。输出:该根,四舍五入到小数点后
思路
五次方程没有求根公式,但题面给出的"端点异号 + 区间内唯一根"正是二分法的全部前提:全程保持 right-left > 1e-12),每轮减半,40 轮后区间宽约
参考代码
Python 版:
python
#!/usr/bin/env python3
# Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
# rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
# rainboy的学习导航网站: https://idx.roj.ac.cn
# create_at: 2026-09-30 01:19
# update_at: 2026-09-30 01:27
LEFT = 1.5 # 题面保证 f(LEFT) > 0
RIGHT = 2.4 # 题面保证 f(RIGHT) < 0
EPS = 1e-12 # 区间宽度缩到 1e-12,比要求的 1e-6 精度小 6 个数量级
def f(x: float) -> float:
"""题面函数 f(x) 在 x 处的取值,用秦九韶(Horner)形式求值。"""
return ((((x - 15) * x + 85) * x - 225) * x + 274) * x - 121
def solve() -> None:
"""在唯一零点已知所在区间上二分,输出四舍五入到 6 位小数的根。"""
left, right = LEFT, RIGHT # 不变量:f(left) > 0 且 f(right) < 0,零点始终被区间夹住
while right - left > EPS:
mid = (left + right) / 2
if f(mid) > 0:
left = mid # 中点为正当,零点落在右半段
else:
right = mid # 中点为负,零点落在左半段
print(f"{(left + right) / 2:.6f}")
if __name__ == "__main__":
solve()C++ 版(同一算法):
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-10-05 06:30
* update_at: 2026-10-05 06:30
*/
#include <cstdio>
// 用秦九韶(Horner)形式计算 f(x),只需常数次乘加,避免高次幂的浮点误差放大
double f(double x) {
return ((((x - 15) * x + 85) * x - 225) * x + 274) * x - 121;
}
int main() {
// 题面保证 f(1.5) > 0 > f(2.4),且区间内有唯一根,直接以此为初始区间
double left = 1.5, right = 2.4;
// 终止条件写在区间宽度上:每轮减半,40 轮后区间宽 < 1e-12,
// 取中点误差 <= 5e-13,远小于 6 位小数要求的 5e-7
const double EPS = 1e-12;
while (right - left > EPS) {
double mid = (left + right) / 2;
if (f(mid) > 0)
left = mid; // f(mid) > 0:中点在根左侧,保留右半区间
else
right = mid; // f(mid) <= 0:中点越过根,保留左半区间
}
printf("%.6f\n", (left + right) / 2);
return 0;
}