- Acwing. 789 数的范围【整数二分】">Acwing. 789 数的范围【整数二分】
- Acwing. 790 数的三次方根【浮点数二分】">Acwing. 790 数的三次方根【浮点数二分】
二分查找是针对某个条件,可以把把解空间分为两类,并通过中点所在的类,每次排除一半的解空间。
Acwing. 789 数的范围【整数二分】
该题的题意让我们找到某个数在排序数组中的坐标范围,比如1 2 2 3 3 4。
由于数组是排好序的,因此我们可以考虑二分来做。
首先我们先确定左边界,我们可以把>=target的划分为右类,
如果我们的中点mid在左类,那mid左边包括mid肯定不是我们要求的答案,砍掉。
最终得到左边界。
int get_left(int target) {int left = 0, right = n - 1;while(left < right) {int mid = (left + right) >> 1;if (d[mid] >= target) {right = mid;} else {left = mid + 1;}}if (d[right] == target) {return right;} else {return -1;}}
右边界的求法类似,我们可以把<=target的划分为左类,
如果我们的中点mid在左类,由于我们要求左类最大的数,因此需要砍掉mid左边的数,mid由于可能是最终解,不能排除。
最终得到右边界。
int get_right(int target) {int left = 0, right = n - 1;while(left < right) {int mid = (left + right + 1) >> 1;if (d[mid] <= target) {left = mid;} else {right = mid - 1;}}if (d[left] == target) {return left;} else {return -1;}}
Acwing. 790 数的三次方根【浮点数二分】
浮点数二分和整数二分类似,依旧是根据某个条件,把解空间分成两类,通过中点所在的类排除一半的解空间。
浮点数二分边界情况比整数二分要简单。
#include <iostream>using namespace std;int main(){double n;cin >> n;double left = -10000, right = 10000;while(right - left > 1e-8) {double mid = (left + right) / 2;if (mid * mid * mid >= n) {right = mid;} else {left = mid;}}printf("%.6f", right);return 0;}
