|
发表于 2023-11-23 17:30:51
|
显示全部楼层
本楼为最佳答案
本帖最后由 柿子饼同学 于 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 是最后答案
复制代码 |
|