首页 > 其他分享 >二分查找和二分答案模板

二分查找和二分答案模板

时间:2023-05-11 10:36:02浏览次数:35  
标签:二分 下标 int mid while 查找 find 模板

1、二分查找

关于二分查找主要有三种模板

模板1 结束条件为 l + 1 == r

查找最后一个 <= x 数的下标 (最大化查找,可行区在左侧)

int find(int x)
{
	int l = 0,r = n + 1; // 开区间,数据存储下标为1~n
    while(l + 1 < r)
    {
		int mid = l + r >> 1;
    	if(a[mid] <= x) l = mid;
   	 	else r = mid;
    }
    return l;
}

查找第一个 >= x数的下标 (最小化查找,可行区在右侧)

int find(int x)
{
	int l = 0,r = n + 1; // 开区间,数据存储下标为1~n
    while(l + 1 < r)
    {
		int mid = l + r >> 1;
    	if(a[mid] >= x) r = mid;
   	 	else l = mid;
    }
    return r;
}

模板2 结束条件为 l == r (y总的板子)

查找最后一个 <= x 数的下标 (最大化查找,可行区在左侧)

int find(int x)
{
	int l = 1,r = n; // 闭区间,数据存储下标为1~n
    while(l < r)
    {
		int mid = l + r + 1 >> 1;
    	if(a[mid] <= x) l = mid;
   	 	else r = mid - 1;
    }
    return l;
}

查找第一个 >= x数的下标 (最小化查找,可行区在右侧)

int find(int x)
{
	int l = 1,r = n; // 闭区间,数据存储下标为1~n
    while(l < r)
    {
		int mid = l + r >> 1;
    	if(a[mid] >= x) r = mid;
   	 	else l = mid + 1;
    }
    return r;
}

模板3 结束条件为 l == r +1(一个OI同学常用的板子)

查找最后一个 <= x 数的下标 (最大化查找,可行区在左侧)

int find(int x)
{
    int ans = 0;
	int l = 1,r = n; // 闭区间,数据存储下标为1~n
    while(l <= r)
    {
		int mid = l + r >> 1;
    	if(a[mid] <= x) ans = mid,l = mid + 1;
   	 	else r = mid - 1;
    }
    return ans;
}

查找第一个 >= x数的下标 (最小化查找,可行区在右侧)

int find(int x)
{
    int ans = 0;
	int l = 1,r = n; // 闭区间,数据存储下标为1~n
    while(l <= r)
    {
		int mid = l + r >> 1;
    	if(a[mid] >= x) ans = mid,r = mid - 1;
   	 	else l = mid + 1;
    }
    return r;
}

上面三个板子中比较好用的是第一个和第三个,第二个板子在 >= x<= x 的mid计算方式不同,所以在编程过程中出错的概率更大。

其中第一个板子 \(l\) 和 \(r\) 都只在各自的可行区移动,也就是说在 <= x 的情况下,下标\(l\)对应的数 一直 <= x, 下标\(r\)对应的数一直 > x

我个人比较喜欢第一个板子,接下来用第一个板子介绍一下浮点二分和二分答案。

浮点二分

double find(double x)
{
	double l = 下界 - 1,r = 上界 + 1;//因为是浮点数,这里l,r不那么精确也行,可以适当扩大范围
	while(r - l > 1e-5)  //因为计算机的精度问题,所以两个浮点数相差1e-5就可以认为是相等的
	{
		double mid = (l + r) / 2;
		if(check(mid)) l = mid;
		else r = mid;
	}
	return l;
}

2、二分答案

2.1 最大化答案(可行区在左侧)

int find()
{
    int l = 下界 - 1,r = 上界 + 1;
    while(l + 1 < r)
    {
        int mid = l + r >> 1;
        if(check(mid)) l = mid;
        else r = mid;
    }
    return l;
}

2.2 最小化答案(可行区在右侧)

int find()
{
	int l = 下界 - 1,r = 上界 + 1;
    while(l + 1 < r)
    {
        int mid = l + r >> 1;
        if(check(mid)) r = mid;
        else l = mid;
    }
    return r;
}
bool check(int x)
{
    //根据可行区不同,编写不同的check函数
}

标签:二分,下标,int,mid,while,查找,find,模板
From: https://www.cnblogs.com/mrneojeep/p/17390305.html

相关文章

  • 标准模板5
    #include<iostream>#include<map>#include<utility>#include<string>usingnamespacestd;intmain(){ multimap<string,string>courses; typedefmultimap<string,string>::iteratorCourseIter; courses.insert(make_pair("C++&qu......
  • 标准模板4
    #include<iostream>#include<map>#include<cctype>usingnamespacestd;intmain(){ map<char,int>s; charc; do{ cin>>c; if(isalpha(c)){ c=tolower(c); s[c]++; } }while(c!='.'); for(map<char,int>::iteratorite......
  • 写C++模板函数的两种形式
    #include<iostream>template<typenameT>autof1(constT&x){std::cout<<x<<std::endl;};autof2=[](constauto&x){std::cout<<x<<std::endl;};intmain(intargc,char**argv){int......
  • 代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素。第一章 数组part01
    今天开始第一天,其实之前也刷过题,也写过博客,可是没有坚持下去;主要是没有动力吧,我又是一个严重的拖延症患者,还好遇到刷到Carl哥的视频,记得是在bilibili分享的二分法视频,感觉讲的挺好的,就加了微信;然后发现有刷题训练营,太适合我这种人了,果断加入,哈哈,废话不多说,开始刷题。  第......
  • 折半查找(二分)
    一、问题描述N个有序整数数列已放在一维数组中, 利用二分查找法查找整数m在数组中的位置。若找到,则输出其下标值:反之,则输出“Not be found!"。二、问题分析二分查找法(也叫折半查找)其本质是分治算法的一种。所谓分治算法是指的分而治之,即将较大规模的问题分解成几......
  • 二分
    寻找重复数寻找重复数classSolution{publicintfindDuplicate(int[]nums){intlen=nums.length;intl=1,r=len-1;while(l<r){intmid=(l+r)/2;intcount=0;for(intnum:......
  • C++标准库和模板库的区别和联系?
    C++标准库包含模板库。C++标准库由三组库构成(std::是个名称空间标识符,C++标准库中的函数或者对象都是在命名空间std中定义的):(1)C库:由C标准库扩展而来,强调结构、函数和过程,不支持面向对象技术。(2)C++库:增加了面向对象的库,包含了既有关键功能的类(3)标准模板库(STL):高效的C++程序库。该......
  • 模板(有序数组)
    6-1有序数组(类模板)分数 10全屏浏览题目作者 何振峰单位 福州大学实现一个类模板,它可以接受一组数据,能对数据排序,也能输出数组的内容。每行输入的第一个数字为0,1,2或3:为0时表示输入结束;为1时表示将输入整数,为2时表示将输入有一位小数的浮点数......
  • C#设计模式14——模板方法的写法
    模板方法(TemplateMethod)是一种设计模式,它定义了一个操作中的算法的骨架,将某些步骤推迟到子类中实现,从而使得子类可以在不改变算法骨架的情况下重新定义算法的某些步骤。作用:使用模板方法可以使得代码的重复度降低,同时也能够避免由于算法中某个特定步骤的改变导致整体算法需要改......
  • 归档 230502 // 二分图
    Sowhynot二分图?二分图二分图总体概念不难。主要是其应用广泛,需要注意什么样的题目可以联系到二分图上来。概念若图\(G\)可将点集\(V\)分成两个互不相交的子集\(X\)和\(Y\),且每条边连接的两个点都满足一个在\(X\)中,一个在\(Y\)中,则称\(G\)为二分图。也就是说,......