二分大致有两类:二分查找和二分答案。
chapter 1:二分查找
1.二分查找思路:如在与有序数列(以升序为例)【1,3,4,7,12,16,98,123,134,435,443,1001,1314,12345,12346】中,要找98.
step1:中间数为123,98<123,在【1,3,4,7,12,16,98】中继续找;
step2:中间数为7,98>7,在【12,16,98】中继续找;
step3:中间数为16,98>16,在【98】中继续找;
step4:中间数为98,98=98,找到。
2.用c++实现:
#include<iostream>
#include<algorithm>
using namespace std;
int a[1000001],f,n;// f为要找的数,n为数组元素个数
bool search(int lef,int rig){
if(lef>rig) return false;
int mid=lef+rig>>1; //相当于int mid=(lef+rig)/2, 不过效率要高一些
if(a[mid]>f) return search(lef,mid-1); //递归
if(a[mid]<f) return search(mid+1,rig); //递归
if(a[mid]==f) return true;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
cin>>f;
if(search(1,n)) cout<<"YES";
else cout<<"NO";
return 0;
}
3.Attention:要保证查找的数列是有序的!!!
chapter 2:二分答案
1.二分答案思路:
二分答案事实上就是在不能用表达式推理出答案时对答案用二分尝试。
2.c++伪代码详解(以查找符合条件的最大值为例):
#include<iostream>
using namespace std;
int answer(int lef,int rig){
if(lef==rig) return rig;
int mid=(lef+rig>>1)+1;
if(mid满足条件) return answer(mid,rig);
return answer(lef,mid-1);
}
int main(){
cout<<answer(答案可能的最小值,答案可能的最大值);
return 0;
}
3.Attention:要保证答案的单调性,即必定存在某个值,使得小于它的值全部不合题意(或符合题意),大于等于它的值全部符合题意(或不合题意)!!!