c++算法之二分

目录

二分法简介

解题步骤

整数二分

模板

例题

输入描述

输出描述

样例输入输出

浮点二分

模板

二分答案(最重要)

模板

例题 跳石头

题目描述

输入描述

输出描述

输入输出样例

例题 肖恩的苹果林

输入描述

输出描述

测试

例题 肖恩的乘法表


二分法简介

二分法是一种高效的查找方法,它通过将问题的搜索范围一分为二(两边具有明显的区别),迭代的缩小搜索范围,直到找到目标或确定目标不存在。

二分法使用于有序数据集合,并且每次迭代可以将搜索范围缩小一半

二分法本质也是枚举,但和暴力枚举不同,二分法利用数据结构的单调性减少了很多不必要的枚举,从而极大的提高了效率,一般可以将O(n)的枚举优化到O(logn)

解题步骤

1.研究并发现数据结构(或答案变量)的单调性

2.确定最大区间[l,r],确保分界点一定在里面,具有一定细节:若以r作为答案,那么答案区间在[l+1,r],若以l为答案,那么答案区间在[l,r-1]

3.确定check函数,一般为传入mid(区间中某个下标),返回mid所属区域或返回一个值,当check函数较简单时可直接判断

4.计算中点mid = (1+r)/2,用check判断该移动l或r指针,具体移动哪个需要根据单调性以及要求的答案来判断。

5.返回l或r,根据题意判断

整数二分

整数二分就是在一个已有的有序数组上,进行二分查找,一般为找出某个值的位置,或者是找出分界点。

这个数组肯定是开的下的,其数组大小一般在1e6以内。

模板

//找到升序数组a中的x第一次出现的位置
int l = 0,r = 1e9;
//注意这里的判断,这样可以保证l,r最终一定收敛到分界点
while(l+1!=r)//l r相邻退出
{int mid = (l+r)/2;//如果a为升序,说明mid偏大了,需要减小mid,就只能将r变小,即r = midif(a[mid]>=x)r = mid;else l = mid;
}
cout<<r<<endl;

例题

给定一个数组,其采用如下代码定义

int data[200];
for(i = 0;i < 200;i++)data[i]=4*i+6;

先给定某个数(在data数组中),请你求出它在数组中的位置。

输入描述

输入一个待查找的整数(该整数一定在数组data中)

输出描述

输出该整数在数组中的指标

样例输入输出

输入262 输出64

#include<iostream>
using namespace std;
int main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int data[200];for (int i = 0; i < 200; i++){data[i] = 4 * i + 6;}int x; cin >> x;int l = -1, r = 199;//为什么是-1 因为最后要返回r r的范围是l+1到r 即0到199while (l + 1 != r){int mid = (l + r) >> 1;//二进制右移一位 相当于÷2if (data[mid] >= x)r = mid;else l = mid;}cout << r << endl;system("pause");return 0;
}

浮点二分

浮点二分不再是在有序数组上做二分查找,而是在某个实数范围内进行查找,因为实数域本身就是单调的,所以也满足单调性,和整数二分主要区别就在于使用的变量类型、退出的判断条件不同。

模板

//计算单调函数f(x)的零点
double l = 0,r = 1e9,eps = 1e-6;
//注意这里的判断条件,这样可以保证l,r最终一定收敛到分界点
while(r-l>=eps)//eps是一个极小量,设置为1e-6较合适
{double mid = (l+r)/2;//f(x)单调递增,f(mid)>=0,说明mid偏大了,需要减小mid,就只能将r变小,即r = midif(f(mid))>=0)r = mid;else l = mid;
}
//最后返回l,r差别不大
cour<< r <<endl;

二分答案(最重要)

二分答案是二分法中最常见也最重要的题型,考察的比较灵活,需要选手从题目中发现某个单调的函数,然后对其二分

常见的模型是:

二分框架(时间复杂度O(logm)+check函数(时间复杂度O(n))

一般情况下,我们会将答案进行二分,然后再枚举出某个可能解后判断其是否可以更优或者是否合法,从而不断逼近最优解

二分答案的题的特征:如果已知某个答案,很容易判断其是否合法或更优。某些贪心问题可能可以转化成二分答案问题

模板

bool check(int mid)
{bool res = true;//do sth to check the authority of midreturn res;
}
int main()
{int l = 0,r = 1e9;while(l+1!=r){int mid = (l+r)/2;//具体写法需要根据题意修改if(check(mid))l = mid;else r= mid;
}
cout<<l<<endl;

例题 跳石头

题目描述

一年一度的"跳石头"比赛又要开始了!

这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间,有 N 块岩石(不含起点和终点的岩石)。在比赛过程中,选手们将从起点出发,每一步跳向相邻的岩石,直至到达终点。

为了提高比赛难度,组委会计划移走一些岩石,使得选手们在比赛过程中的最短跳跃距离尽可能长。由于预算限制,组委会至多从起点和终点之间移走M 块岩石(不能移走起点和终点的岩石)。

输入描述

输入文件第一行包含三个整数 L,N,M,分别表示起点到终点的距离,起点和终点之间的岩石数,以及组委会至多移走的岩石数。

接下来 N 行,每行一个整数,第 i 行的整数 (0<Di<L)表示第i 块岩石与起点的距离。这些岩石按与起点距离从小到大的顺序给出,且不会有两个岩石出现在同一个位置。

其中,0≤5×104,1≤1090≤M≤N≤5×104,1≤L≤109

输出描述

输出只包含一个整数,即最短跳跃距离的最大值。

输入输出样例

    输入
    25 5 2
    2
    11
    14
    17
    21 

    输出
    4

#include<iostream>
using namespace std;
using ll = long long;
const int N = 5e4 + 9;
int a[N], L, n, m;int check(int mid)
{//当最远跳跃距离为mid的情况下,至少需要搬走多少块石头int res = 0,lst=0;for (int i = 1,lst = 0; i <= n; i++)//lst表示上一块石头的位置{if (a[i] - a[lst] < mid){res++;continue;}lst = i;}if (L - a[lst] < mid){return m + 1;//这种情况不行,因为最后一块石头不能被搬走}return res;
}
int main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);cin >> L >> n >> m;for (int i = 1; i <= n; ++i)cin >> a[i];ll l = 0, r = 1e9 + 5;while (l + 1 != r){ll mid = (l + r) / 2;if (check(mid) <= m)l = mid;else r = mid;}cout << l << endl;return 0;
}

例题 肖恩的苹果林

肖恩有一大片农田,农田中有 N 个可以种植苹果树的位置。这些位置都分布在一条直线上,坐标是 x1,x2,..,xN 。肖恩得到了 M 个树苗,需要种到农田中的对应位置.
我们都知道两棵苹果树种的距离如果太近的话会互相争抢养分,导致两棵苹果树都会营养不良。所以肖恩认为相邻两棵苹果树之间的最近距离越大越好,那么请你帮肖恩算算最大的最近距离是多少?

输入描述

第一行输入两个整数N和M,两个数的意义和题面中描述相同
第二行输入N个数字,第i个数字 xi表示第i个可以种植苹果树的位置

输出描述

输出一个数字表示最大的最近距离

#include<iostream>
#include<algorithm>
using namespace std;
using ll = long long;
const int N = 5e4 + 9;
int x[N], n, m;int check(int mid)
{int res = 0,lst=0;for (int i = 1, lst = 0; i <= n; i++){if (lst && x[i] - x[lst] < mid)continue;res++, lst = i;}return res;
}
int main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);cin >>n >> m;for (int i = 1; i <= n; ++i)cin >> x[i];sort(x + 1, x + 1 + n);ll l = 0, r = 1e9 + 5;while (l + 1 != r){ll mid = (l + r) / 2;if (check(mid) >= m)l = mid;//最多能种多少树 大于m 说明间隙小了 要增大else r = mid;}cout << l << endl;return 0;
}

测试

5 3
1 3 4 8 9
3

例题 肖恩的乘法表

#include<iostream>
#include<algorithm>
#include<windows.h>
using namespace std;
using ll = long long;
const int N = 5e4 + 9;
ll n, m, k;ll check(ll mid)
{ll res = 0;for (int i = 1; i <= n; i++)//每一行多少个数字<mid{res += min(m, mid / i);}return res;
}
int main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);cin >>n >> m>>k;ll l = 0, r = 1e14;while (l + 1 != r){ll mid = (l + r) >> 1;if (check(mid) >= k)r = mid;else l = mid;}cout << r << endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/618419.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android 13.0 Launcher3长按app弹窗设置为圆角背景功能实现二

1.前言 在13.0的系统ROM定制化开发中,在进行一些Launcher3的定制化开发中,在使用app的弹窗的功能时,会弹出应用信息和 微件之类的内容,所以在定制需求中,需要默认设置为圆角背景,接下来就来分析下相关功能的实现如图: 2.Launcher3长按app弹窗设置为圆角背景功能实现二的…

基于JAVA的固始鹅块销售系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 鹅块类型模块2.3 固始鹅块模块2.4 鹅块订单模块2.5 评论管理模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 鹅块类型表3.2.2 鹅块表3.2.3 鹅块订单表3.2.4 鹅块评论表 四、系统展示五、核心代码5.…

每日一练:LeeCode-104. 二叉树的最大深度【二叉树】

本文是力扣LeeCode-104. 二叉树的最大深度 学习与理解过程&#xff0c;本文仅做学习之用&#xff0c;对本题感兴趣的小伙伴可以出门左拐LeeCode。 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例…

WAMP apache 无法启动(端口 80 未使用)

这段时间系统重装后&#xff0c;安装WAMP Server&#xff0c;装好后点击启动绿了下然后又变成了黄色&#xff0c;托盘图标无论是左键点击还是右键点击都没有反应&#xff0c;wampapache64服务也启动不起来&#xff0c;提示“windows不能在本地计算机启动wampapache”&#xff0…

【npm link】Node命令中的npm link命令的使用,还有CLI全局命令的使用,开发命令行工具必不可少的部分

&#x1f601; 作者简介&#xff1a;一名大四的学生&#xff0c;致力学习前端开发技术 ⭐️个人主页&#xff1a;夜宵饽饽的主页 ❔ 系列专栏&#xff1a;NodeJs &#x1f450;学习格言&#xff1a;成功不是终点&#xff0c;失败也并非末日&#xff0c;最重要的是继续前进的勇气…

Mysql查询与更新语句的执行

一条SQL查询语句的执行顺序 FROM&#xff1a;对 FROM 子句中的左表<left_table>和右表<right_table>执行笛卡儿积&#xff08;Cartesianproduct&#xff09;&#xff0c;产生虚拟表 VT1 ON&#xff1a;对虚拟表 VT1 应用 ON 筛选&#xff0c;只有那些符合<join_…

yapi无法注册解决,使用yapi pro即可注册,接口文档生成,java,json

1.气屎我了&#xff0c;直接用yapi pro就可以用&#xff0c;害的我弄了半天 2.地址&#xff1a;https://yapi.pro/login 3.yapi pro比较卡顿。开启无痕模式轻松解决该问题&#xff08;手动狗头&#xff09;祝你开启新大陆 yapi pro yapi

ChatGPT能帮助我们人类做什么

一、ChatGPT可以在多个方面帮助人类&#xff1a; 回答问题&#xff1a; ChatGPT可以回答各种问题&#xff0c;提供信息和解释概念。 创造性写作&#xff1a; 它可以生成文章、故事、诗歌等创意性文本。 学术辅助&#xff1a; ChatGPT可以辅助学术研究&#xff0c;提供解释、背…

DNS解析和主从复制

一、DNS名称解析协议 二、DNS正向解析 三、DNS主从复制 主服务器 从服务器

安装rlwrap库出现问题

背景&#xff1a;oracle的sqlplus还是那么难用&#xff0c;不知道为什么不打包解决这个问题&#xff0c;留给用户&#xff0c;内核硬&#xff0c;就是猖狂。废话不多说。下载解压rlwrap-0.46.1.tar.gz;进入/tmp/database/rlwrap-0.46.1源码包&#xff0c;./configure checki…

RT-Thread基于AT32单片机的CAN应用

1 硬件电路 2 RT-Thread驱动配置 RT-Studio中没有CAN相关的图形配置&#xff0c;需要手动修改board.h。在board.h的末尾&#xff0c;增加相关的BSP配置。 #define RT_CAN_USING_HDR #define BSP_USING_CAN13 IO配置 at32_msp.c中的IO配置是PB9和PB10&#xff0c;掌上实验室V…

轻松掌握构建工具:Webpack、Gulp、Grunt 和 Rollup 的使用技巧(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

STM32——高级定时器输出指定个数PWM波原理及实战

1.高级定时器简介&#xff08;TIM8、TIM1&#xff09; 相比于通用定时器特性&#xff1a; 1&#xff09;重复计数器 2&#xff09;死区时间带可编程的互补输出 3&#xff09;断路输入&#xff0c;用于将定时器的输出信号置于用户可选的安全配置中 2.高级定时器框图 3.重复计数…

Sectigo增强型多域名SSL证书买一年送一月

Sectigo EV增强型多域名SSL证书是一种高安全性的数字证书。相比于DV基础型的多域名SSL证书和OV企业型的多域名SSL证书&#xff0c;EV增强型多域名SSL证书功能更多、安全等级更高&#xff0c;但是相应的&#xff0c;这款SSL证书的审核也比较严格。今天就随SSL盾小编了解Sectigo旗…

Oracle篇—实例中和name相关参数的区别和作用

☘️博主介绍☘️&#xff1a; ✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ ✌✌️擅长Oracle、MySQL、SQLserver、Linux&#xff0c;也在积极的扩展IT方向的其他知识面✌✌️ ❣️❣️❣️大佬们都喜欢静静的看文章&#xff0c;并且也会默默的点赞收藏加关注❣…

基于JAVA开发的数字化智慧工地管理平台源码,可私有化部署、带可视化大屏

智能工地应用价值 智慧工地现场构建了基于物联网的智能化数据传感器通用的管理平台。利用计算机、人工智能、无线通信&#xff0c;全天候现场监视、施工检查、质量管理、服务&#xff0c;提高数字化管理、安全、绿色、施工等现场管理能力&#xff0c;标志着现场管理进入信息化时…

20240106----重返学习-在VMware里给centos7设置静态IP地址

在VMware里给centos7设置静态IP地址 场景 学习nginx中&#xff0c;想要设置静态IP地址&#xff0c;以便让win10主环境中的Xshell里能够连接到VMware中的CentOS7上&#xff0c;进而可以在Xshell里进行操作。可以做到如复制粘贴之类的&#xff0c;而不是在虚拟机中的默认终端上…

css如何让两个元素在同一水平线上(文字和svg图片)

一开始写发现这两者不在同一水平线 起初用margin-top margin-bottom来协调 发现效果并不好 1&#xff1a;写法僵硬 2&#xff1a;margin会把div撑破&#xff0c;达不到预期效果&#xff08;padding也是&#xff09; 3. 加了flex布局 之后, 因为我这个是在表格里面,无法居中…

实录分享 | 央企大数据平台架构发展趋势与应用场景的介绍

分享嘉宾&#xff1a; 孟子涵-中国华能集团信息中心平台架构师 2021年华能就与Alluxio建立了合作&#xff0c;共同写了整个华能统一纳管的架构方案。这个方案我认为是现在我们在央企里边比较核心的一套体系&#xff0c;能让全集团所有我们认为重要的数字化资源实现真正的统一集…

【K8s学习】

k8s的简单执行流程&#xff1a; Kubernetes Master&#xff08;API Server、Scheduler等组件&#xff09;负责调度Pod到合适的Node上。 当Pod被调度到某个Node时&#xff0c;该Node上的kubelet代理会收到指令并开始执行Pod的生命周期管理任务&#xff0c;包括创建、监控和终止P…