二分算法(整数)
重要思路:
根据两个条件的情况来做判断(具体看题目中所要求的条件)
首先 可以从简单的例子来说 二分我的理解就是不断的分,用mid这个值来寻找符合条件的那个数或返回正确的数字的位置(下标)
【 条件1 】【 条件2 】
第一种情况 : 满足条件1或不满足条件1
1.确定mid的值 mid = l+r+1>>1 (加上1是因为下边有减一的情况,防止死循环)
2. 如果check的结果是true ,满足条件1 ,那么就说明mid的这个数的位置一定在条件1的这个区间内 也就是说 l 到 r 的这个区间就可以缩小或更新成 mid到 r;
对应代码就是 l= mid;
3. 如果check的结果是false 就是不满足条件1 那么mid的位一定在条件2中 那么原先的区间
l 到 r 这个区间就要更新 成 l到mid-1 (这里对mid值为什么要加一再除以2)
对应代码就是 r=mid-1; (数组中的下标是从0开始的 所以-1)
第二种情况 : 满足条件2或不满足条件2
1.确定mid的值是l+r>>1;
2.check 条件2 true 更新区间成 l到mid
对应代码是 r= mid;
3. check 的结果是false 更新区间为 mid+1到r
对应代码是 l=mid+1;
二分算法模板题目
详细见ACwing的789题 数的范围
输入一个数组 和访问次数和x这个数字
然后返回出 x在这个数组中出现的位置 不存在就输出-1
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+10;
int n,m;
int q[N];
int main (void)
{
cin>>n>>m;
for(int i=0;i<n;i++) cin>>q[i];
while(m--)
{
int x;
cin>>x;
//定义边界
int l =0,r = n-1;
while(l<r)
{
int mid = l+r>>1;
if(q[mid] >= x) r = mid; //用的是模板2
else l =mid+1;
}
if(q[l] != x) cout<<"-1 -1"<<endl;
else
{
cout<<l<<" ";
int l=0,r = n-1;
while(l<r)
{
int mid = l+r+1>>1;
if(q[mid]<=x) l =mid;
else r = mid-1;
}
cout<<l<<endl;
}
}
return 0;
}