二分查找
整数二分
特点
-
单调序列一定可以二分查找,但二分查找不一定是单调序列
-
整数二分,有两套模板
-
二分是一定会得到一个答案的,一定有解。 但是这个解不一定是满足题目要求,题目可能是无解的。
-
当区间内只有一个值时就是二分的结果。 二分一定有结果,但结果不一定满足题目
-
确保最后结果落在只包含一个元素的区间。 即确保通过二分最后结果为一个确定的值,不能是一个区间。(整数二分的特点)
思想
第一套模板
int mid = l + r + 1 >> 1 //注意当 l = mid 则必须加1, 因为当 l = r - 1 时,如果不加1,则 l + r >> 1 依旧为 l, 那么 l = mid 仍然是 [l, r] 循环完区间没有发生变化,会导致死循环。
if (check(mid))
l = mid
[mid, r] //待求整数在区间[mid, r]中
else
r = mid - 1
[l, mid - 1] //待求整数在区间[l, mid - 1]中
第二套模板
int mid = l + r >> 1
if (check(mid))
r = mid
[l, mid] // 待求整数在区间[l, mid]中
else
l = mid + 1
[mid + 1, r] //待求整数在区间[mid + 1, r]中
核心思想: 写一个check(mid)函数,判断是l = mid 还是 r = mid
当二分查找不存在这个数的时候,返回数组中第一个大于等于这个数的值
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
return 0;
}
浮点数二分
特点
- 不涉及整数二分的边界加减问题
思想
- 同整数二分类似,最后要保证二分的区间越来越小
求平方根
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
double x;
cin >> x;
double l = 0, r = x;
while (r - l > 1e-8)
{
double mid = (l + r) / 2;
if (mid * mid <= x) l = mid;
else r = mid;
}
cout << l << endl;
return 0;
}