引言:
有一个二分搜索的经典问题——猜数。
犹记得小学时候,经常在中央二套看一个电视节目,名字好像叫啥,对,是“幸运52”,李咏大叔主持的,当时就有一个游戏是“猜商品的价格”。游戏规则大概是这样的,给你看一件商品,规定限时多少秒,让你猜价格是多少,李咏大叔通过你猜的价格提示“高了”还是“低了”,然后你根据他的提示,继续猜,直到猜到为止或时间截止。
-_-||| 当时这个游戏很多人都傻地从一个数开始依次猜,比如一个电视1980,有些人就可能从1500猜,然后提示低了,就1501, 1502…这样怎么也不可能在规定时间内猜到。
我们可以这样猜:
一件商品的价格为599
给定一个范围0~2000
1.先猜1000 高了
2.那就猜500 低了
3.那就750 高了
4.那625呢 高了
5.就562了 低了
6.那593 低了
7.609 高了
8.601 高了
9.597 低了
10.599 ok
可见猜10次即可。这就是二分查找的精髓所在,通过一半一半缩小范围最后就能确定到所要查找到的元素。
#include<cstdio>
using namespace std;
int k;//1~2000里的数
int solve(int k)
{
int count = 0 ;
int lb = 0, ub = 2000;
while(ub - lb > 1)
{
count ++;
int mid = (lb+ub)/2;
printf("%d\n",mid);
if(mid < k) lb = mid;
else if(mid > k) ub = mid;
else break;
}
return count;
}
int main()
{
scanf("%d",&k);
printf("%d\n",solve(k));
return 0;
}
二分搜索法:
这个方法是通过不断缩小解可能存在的范围,从而求得问题的最优解的方法。也就是说在“求满足某个条件C(x)的最小的x”这一问题上,对于任意满足C(x)的x,如果所有的x’>=x也满足C(x’)的话,我们就可以用二分搜索来求得更小的x。首先我们将区间的左端点初始化为不满足C(x)的值,右端点初始化为满足C(x)的值。然后每次取中点mid = (lb + ub)/2,判断C(mid)是否满足并缩小范围,直到(lb, ub]足够小了为止。最后ub就是要求的最小值,最大值同理。
典型应用:
1.查找值
2.最大化最小值(最小化最大值)
3.最大化平均值
心得:
在我看来,一些能够用二分法解决的问题都是那些可以通过直接假设一些求的结果带进去并能够很容易判断是否符合题目条件的问题,这类问题就可以通过二分法假设最后结果带入题目规定的条件看是否符合,然后不断缩减范围知道求得最值。