二分模板

二分答案的写法有很多模板,但使用的情况各不相同
前两种模板:都是 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


}

找最值都可以:

  1. 找最小值返回 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位置

}
  1. 找最大值最终返回 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  
}

posted @ 2023-10-18 14:21  merlinkkk  阅读(67)  评论(0)    收藏  举报