本帖最后由 柿子饼同学 于 2023-11-23 17:35 编辑
以下是两种模板 , 分别是整数域上的二分 和 实数域上的二分(可以是小数的)
Check(x) 代表 x 作为答案满不满足条件 , 是 1 就满足 , 0 就不满足 , 根据实际需要编写
整数的二分 :
// L, R 是自己设的 最小/最大值
int l = L, r = R, mid, res;
while(l <= r){
mid = (l + r) / 2;
// 这个方法是求最大的符合条件的值, l 在增大
if(Check(mid)) l = mid + 1, res = mid;
else r = mid - 1;
// 求出最小的符合条件的, 看 r 每次在缩小
// if(Check(mid)) r = mid - 1, res = mid;
// else l = mid + 1;
// 两种情况自己看着用
}
// 过后 res 就是答案
实数上二分double l = L, r = R, mid, res;
double eps = 1e-12; // 极小值, 如果 r - l < eps 就可以看作相等, eps的设置要根据需要, eps 越小答案精度越高
while(r - l > eps){
mid = (l + r) / 2;
// 求最大的符合条件的答案
if(Check(mid)) l = mid, res = mid;
else r = mid;
// 求最小的符合的答案
// if(Check(mid)) r = mid, res = mid;
//else l = mid;
}
// res 就是最后的答案
也可以指定循环次数 , 不用 eps , 循环次数自己调 , 次数越多精度越高int l = L, r = R, mid, res;
for(int i = 0; i < 50; i++){
mid = (l + r) / 2;
if(Check(mid)) r = mid, res = mid;
else l = mid;
// 另一种情况不用我说了吧
}
// res 是最后答案
|