二分答案的写法有很多模板,但使用的情况各不相同
前两种模板:都是 while(l < r)
,但是会有区别的,区别在代码注释中有体现。
后两种模板:都是 while(l <= r)
, 也是在返回上有区别。
这是最大值最小
int main()
{
int l;
int r;
while(l < r)
{
int mid = (l + r)/ 2;
if(check())
{
r = mid; // 这里是 r = mid, 说明[l,mid]是合法范围
}
else
{
l = mid + 1; // [l,mid]这个范围都不是合法范围,所以下一次查找直接从 l = mid + 1开始了
}
//最后的l,r是答案 因为 l == r ,最终就是答案。
}
}
这是最小值最大
int main()
{
int l;
int r;
while(l < r)
{
int mid = (l + r + 1)/ 2; // 这里要 l + r +1 要不然会死循环
if(check())
{
l = mid; // mid这个位置 满足条件之后 查找 [mid , right]的位置, 所以l移到mid的位置
}
else
{
r = mid - 1; // [mid,r] 不满足条件, 所以要移到满足条件的一方, r = mid - 1
}
}
//最后的l,r是答案 因为 l == r
}
找最值都可以:
- 找最小值返回
r
int main()
{
int l;
int r;
while(l <= r)
{
int mid = (l + r )/ 2;
if(check())
{
l = mid - 1;
}
else
{
r = mid + 1;
}
}
//最终 l == r + 1, 找最小值返回r,返回r位置
}
- 找最大值最终返回
l
中间保留保存最佳值
int main()
{
int l;
int r;
while(l <= r)
{
int mid = (l + r )/ 2;
if(check())
{
ans = mid; // 这里需要保证 check()函数是找最佳值的位置的。
// 这个位置已经满足一个位置了,再往mid - 1位置找看是否还有更佳位置
l = mid - 1;
}
else
{
r = mid + 1;
}
}
//答案是ans
}
标签:二分,满足条件,int,mid,while,main,模板
From: https://www.cnblogs.com/IOIAKmerlin/p/17772257.html