点击查看代码
#include<cstdio>
#pragma warning(disable:4996)
//查找序列中等于x的元素的位置
//A[]是已知的严格递增序列,left为二分下界,right为二分上界,x为待查数字
//二分区间为闭区间[left,right],区间初始值是[0,n-1]
int binarySearch(int A[], int left, int right, int x) {
int mid; //mid是left和right的中点
while (left <= right) {
//不要使用mid=(left+right)/2,当left和right较大时两者相加可能超出int范围
mid = left + (right - left) / 2; //求mid
if (A[mid] == x) return mid; //找到x返回下标
else if (A[mid] > x) {
right = mid - 1; //A[mid]大于x时,进入[left,mid-1]范围查找
}
else {
left = mid + 1; //A[mid]小于x时,进入[mid+1,right]范围查找
}
}
return -1; //查找失败时返回-1
}
//查找序列中第一个大于等于x的元素的位置
//二分区间为闭区间[left,right],区间初始值是[0,n],注意初始右边界是n而不是n-1,
//因为如果待查数字x比序列中所有元素都大,此时它应该放在A[n]位置而不是A[n-1]
int lower_bound(int A[], int left, int right, int x) {
int mid;
while (left < right) { //left==right时找到该唯一位置
mid = left + (right - left) / 2;
if (A[mid] >= x) { //A[mid]大于等于x,进入[left,mid]范围查找
right = mid;
}
else {
left = mid + 1; //A[mid]小于x,进入[mid+1,right]范围查找
}
}
return left; //返回夹出来的位置,也可以返回right
}
//查找序列中第一个大于x的元素的位置
//二分区间为闭区间[left,right],区间初始值是[0,n]
int upper_bound(int A[], int left, int right, int x) {
int mid;
while (left < right) { //left==right时找到该唯一位置
mid = left + (right - left) / 2;
if (A[mid] > x) {
right = mid; //A[mid]大于x,进入[left,mid]范围查找
}
else {
left = mid + 1; //A[mid]小于等于x,进入[mid+1,right]范围查找
}
}
return left; //返回夹出来的位置,也可以返回right
}
//解决“寻找有序序列第一个满足某条件的元素的位置”问题的固定模板
//二分区间为闭区间[left,right],初始值必须能覆盖解的所有可能取值
int solve(int left, int right) {
int mid;
while (left < right) { //left==right时找到该唯一位置
mid = left + (right - left) / 2;
if (条件成立) { //条件成立,则第一个满足条件的元素的位置<=mid
right = mid; //进入[left,mid]范围查找
}
else { //条件不成立,则第一个满足该条件的元素的位置>mid
left = mid + 1; //进入[mid+1,right]范围查找
}
}
return left; //返回夹出来的位置,也可以返回right
}