模板一 向左查找
while (l < r) {
int mid = (l + r) / 2;
if (check(mid)) {
r = mid; // check()判断mid是否满足性质
} else {
l = mid + 1;
}
}
模板二 向右查找
while (l < r) {
int mid = (l + r + 1) / 2;
if (check(mid)) {
l = mid; // check()判断mid是否满足性质
} else {
r = mid - 1;
}
}
模板三 浮点数二分
while(r-l>1e-2) //需要一个精度保证
{
double mid = (l + r) / 2;
if (check(mid)) l = mid; //或r = mid;
else r = mid; //或l = mid;
}
例题1
链接
[NOIP2001 提高组] 一元三次方程求解 - 洛谷https://www.luogu.com.cn/problem/P1024
代码
#include <bits/stdc++.h>
using namespace std;
double a, b, c, d;
double f(double i) {
return a * i * i * i + b * i * i + c * i + d;
}
int main () {
cin >> a >> b >> c >> d;
for (double i = -100; i <= 99; i++) {
if (f(i) == 0)
printf("%.2lf ", i);
else if (f(i) * f(i + 1) < 0) {
double l = i, r = i + 1, mid;
while (r - l >= 0.001) {
mid = (l + r) / 2;
if (f(l) * f(mid) <= 0) {
r = mid;
} else {
l = mid;
}
}
printf("%.2lf ", r);
}
}
return 0;
}
例题2
链接
立方根 - 洛谷https://www.luogu.com.cn/problem/B3627
代码
#include <bits/stdc++.h>
using namespace std;
int main () {
double n;
cin >> n;
double l = -10000, r = 10000;
while (r - l > 1e-8) {
double mid = (l + r) / 2;
if (mid * mid * mid > n) {
r = mid;
} else {
l = mid;
}
}
cout << fixed << setprecision(6) << l << endl;
return 0;
}