二分(整数、小数)
二分:
二分的本质是将集合分为连续的两个部分,其中一部分满足条件,而另一部分不满足条件
我们使用二分来找寻满足条件的边界点或者不满足条件的边界点

按照需要寻找的边界点将二分分为两种
1.寻找满足某一条件的第一点,即上图绿色区间的左边界点,此时将区间分为[l,mid] 和 [ mid+1 , r]
//区间被分成[l,mid] 和 [mid+1,r]时 int f(int l,int r) { while(l<r) { int mid = l+r >>1; if(check(mid)) r=mid; else l = mid ; } return 1; }
2.寻找不满足条件的最后一点,即上图红色区间的右边界点,此时将区间分为[l,mid-1] 和 [mid,r]
//区间被分成[l,mid-1] 和 [mid,r]时
int f(int l,int r)
{
while(l<r)
{
int mid = l+r+1 >>1;
if(check(mid)) l=mid;
else r = mid-1;
}
return 1;
}
整数二分:
题目

题解:
#include<bits/stdc++.h>
using namespace std;
const int N=1e6 + 10;
int n,m;
int q[N];
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
{
scanf("%d",&q[i]);
}
while(m--)
{
int k ;
cin>>k;
int l=0,r=n-1;
while(l<r)
{
int mid = l+r>>1;
//if(q[mid]>= k) r =mid ;
//else l= mid +1;
if(k > q[mid]) l = mid +1;
else r = mid ;
}
if(q[l]!= k ) 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]<= k) l = mid ;
else r= mid -1;
}
cout<<r<<endl;
}
}
}
小数二分
小数二分要比整数二分简单的多,由于精度大,并且无论区间怎么变化,要求的结果始终在区间 [ l,r ]内部,所以判断条件可以写为
while( ( r - l ) > 1e -6 )
而且无需担心死循环问题,可以直接判断让 l =mid 或者让 r =mid ;
题目见:https://www.cnblogs.com/LHJ822/p/17241276.html

浙公网安备 33010602011771号