浮点数二分的模板
https://www.acwing.com/problem/content/792/
C++ 代码
#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-8; // eps 表示精度,取决于题目对精度的要求,6位小数,就是1e-8,5位就是1e-7
//三次方根:浮点数的二分,说白了就是个试,找到了算,但不是傻找,而是一半一半找。
int main() {
double x;
cin >> x;
double l = -10000; //这个边界有意思,注意左右边界
double r = 10000;
while (r - l > eps) { //浮点数差逼近了一个极小值,表示找到了相似值
double mid = (l + r) / 2;
if (mid * mid * mid >= x) r = mid; //计算三次方根
else l = mid;
}
printf("%.6lf
", l); //默认保留6位小数
return 0;
}
本题:
1、值的范围 ([-100,100]),可以用来遍历,用整数(i)来遍历,根就在它附近。
2、任意两根之差不小于1,可以处理完一个(i)后,再一个可以直接用来加1进行再次探测。
3、计算公式:
double f(double x) {
return a * x * x * x + b * x * x + c * x + d;
}
4、精度控制,一般浮点数二分 1e-8足够。
5、注意题目中的提示:
这样,就不用每个可能区间全部都去深度二分了,减少了大量的计算。
6、最关键的:
特判
!!!因为可能边界值就是答案,比如整数5,这时再去二分[5,6]就没有意义,注意特判!!!
#include<bits/stdc++.h>
using namespace std;
const double eps = 1e-8;
double a, b, c, d;
//方程
double f(double x) {
return a * x * x * x + b * x * x + c * x + d;
}
int main() {
//输入
cin >> a >> b >> c >> d;
double x, y, mid;
for (int i = -100; i <= 100; i++) {
x = i, y = i + 1;//两个指针
//边界
if (f(x) == 0) {
printf("%.2f ", x);//如果符合条件则直接输出
continue;
}
//如果其中有解就开始二分
if (f(x) * f(y) < 0) { //题目中有提示
//精度要求
while (y - x >= eps) {
mid = (x + y) / 2;
if (f(x) * f(mid) <= 0)y = mid;//判断解在哪个区间
else x = mid;
}
printf("%.2f ", x);
}
}
return 0;
}