【算法每日一练]-二分题型(保姆级教程 篇1) #模板篇

本篇是模板篇

目录

二分查找:

最左模板:

最右模板:

二分精确:

lower_bound和upper_bound

进阶用法lower_bound


     

     

二分查找:

        

我做过的所以二分查找题型基本可以分为两种:最左模型和最右模型

最左模板:

有重复数时候返回最左边的重复数,找不到时候返回第一个大于此数的下标。

(别看写了这么多,其实模板代码就是哪个while循环)

        

#include                   //二分查找(必须有序)
using namespace std;
const int INF=1e5;
int main(){
	int a[100]={5,5,5,5,7,8,9,9,11,13,14,14,15};
    //如果是逆序的,那么在判断时候把a[mid]>=x变成a[mid]<=x即可
	for(int i=13;i<100;i++)a[i]=INF;//查找数组时候,千万不要越界查找
	int mid=0,l=0,r=100,x;
	cin>>x;
	while(l<=r){        
		mid=(l+r)>>1;           //最左二分模板。有重复数时,返回第一个(可以用2,3定理证明)
		if(a[mid]>=x) r=mid-1;  //若找不到,则返回第一个大于此数的下标(故若过大,则返回最后一个元素下标+1)
		else l=mid+1;
	}
	cout<

 解释一下我自己探索时候发现的2,3定理:这种二分最终状态要么是处理2个数要么就是3个数(mid加减1)

         

最右模板:

有重复数时候返回最右边的重复数,找不到时候返回最后一个小于此数的下标。

(别看写了这么多,其实模板代码就是哪个while循环)

       


#include                   //二分查找(必须有序)
using namespace std;
const int INF=1e5;
int main(){
	int a[100]={5,5,5,5,7,8,9,9,11,13,14,14,15};
    //如果是逆序的,那么在判断时候把a[mid]>=x变成a[mid]<=x即可
	for(int i=13;i<100;i++)a[i]=INF;//查找数组时候,千万不要越界查找
	int mid=0,l=0,r=100,x;
	cin>>x;
	while(l<=r){      
		mid=(l+r)>>1;            //最右二分模板:若有重复数时,返回最后一个
		if(a[mid]<=x) l=mid+1;   //若找不到,则返回最后一个小于此数的下标(故若过大,则返回最后一个元素下标)
		else r=mid-1;
	}
	cout<

     

二分精确:

这个最好记了,不用管返回l还是r

        

#include                  
using namespace std;
int main(){                       //二分精确
	double l=0,r=10,mid=0,x;
	cin>>x;
	while(r-l>0.001){           //这里控制精度
		mid=(l+r)/2;
		if(mid>=x) r=mid;      //等号不影响
		else l=mid;
	}
	cout<

       

lower_bound和upper_bound

这两个函数都是针对数字的,字符可以使用find方法

如果恰存在该值,lower_bound返回第一个下标的地址(最左下标),upper_bound返回最后一个的下标 +1的地址(最右下标)

如果不存在该值,都返回第一个大于此数的下标 的地址 (找不到就返回最后的下标+1 也就是end减begin的值)

剩下的不解释了,看注释吧,我全都标记了!!!

        

#include 
using namespace std;
int main(){
	int a[10]={1,2,3,4,5,5,7,8,9,10};
//如果恰存在该值,lower_bound返回第一个下标(最左下标),upper_bound返回最后一个的下标 +1(最右下标)
	int pos1=lower_bound(a,a+10,5)-a;//第一个大于或等于的下标    5的下标为4
	int pos2=upper_bound(a,a+10,5)-a;//第一个大于的下标          7的下标为6
	//如果不存在该值,都返回第一个大于此数的下标  (找不到就返回最后的下标+1 也就是end减begin的值)
	int pos3=lower_bound(a,a+10,11)-a;
	int pos4=upper_bound(a,a+10,11)-a;
	cout<

        

进阶用法lower_bound

(struct自定义比较,此时lower_bound已经只是一个名字了,功能已经被你修改了)

        

#include 
using namespace std;
struct node{
	int x;int y;
}no[10];
struct cmp{    //在结构体cmp中重载()运算符,后面有3个const
	bool operator() (const node a,const node b)const{
		if(a.x==b.x)return a.y

今天讲了很多干货,好好体会一下啊

你可能感兴趣的:(算法,数据结构,c++,动态规划,贪心算法)