当前位置: 首页 > news >正文

蓝桥杯:C++二分算法

在基本算法中,二分法的应用非常广泛,它是一种思路简单、编程容易、效率极高的算法。蓝桥杯软件类大赛中需要应用二分法的题目很常见。

二分法有整数二分和实数二分两种应用场景

二分法的概念

二分法的概念很简单,每次把搜索范围缩小为上一次的1/2,直到找到答案为止。

二分法的效率很高,只需计算log(n)次。

下面介绍二分法的模板代码bin_search()函数:

我们用猜数字的例子,先给数组初始化,然后定义你要猜的数,用二分法效率高。

对于二分法的讲解非常细致,都在注释中。

#include<bits/stdc++.h>
using namespace std;
int a[1000];
int bin_search(int *a, int n, int x) {   //在数组a中查找数字x,返回位置int left = 0, right = n;	//left 通常初始化为 0,表示搜索范围的左边界是数组的第一个元素;right通常初始化为 n(数组的长度),表示搜索范围的右边界是数组的最后一个元素的下一个位置。while (left < right) {int mid = left+(right-left)/2;   //mid的标准写法,建议这样写,不能用(left+right)/2,有可能会整数溢出的。 if (a[mid] >= x) right = mid;   //x小,在左边,把右边的一半砍掉,这里就不用加1了,我们本身就是大于等于x。 else             left = mid+1;	//加1的原因是我们要跳过 a[mid] 这个元素,因为它小于 x,我们要的是等于x的元素 cout<<a[mid]<< " ";              //输出猜数的过程    如果你想省略过程,可以注释掉这一行的输出语句。 }return left;    //返回left所在的索引,不要牵扯到right,避免混淆,right一开始是索引的下一个位置。 
}
int main() {int n = 100;for(int i=0; i<n; i++) a[i]=i+1;    //赋值,数字1~100int test = 54;                      //猜54这个数int pos = bin_search(a,n,test);cout<<"\n"<<"test="<<a[pos];    
}

bin_search()有3个重要点:区间左端点left、区间右端点right、二分的中位数mid。每次把区间缩小一半,把left或right移动到mid;直到left = right为止,即找到答案所处的位置。

二分法的作用:

二分法可以把一个长度为n的有序序列上O(n)的查找时间优化到O(logn)。

注意应用二分法的前提:序列是有序的,按从小到大或从大到小排序。

无序的序列无法二分,如果是无序的序列,则应该先排序再对其进行二分,先排序再二分,排序的复杂度是O(nlog2(n)),二分的复杂度是O(log2(n))。排序加二分的总复杂度是O(nlog2(n))。如果使用暴力法,直接在无序的n个数里面查找,最多查找n次,复杂度是O(n)的,比先排序再二分快。如果不是查找一个数,而是查找m个数,那么先排序再做m次二分的计算复杂度是O(nlog2(n)+ mlog2(n)),而暴力法的复杂度是O(mn),此时二分法远好于暴力法。

整数二分

在单调递增序列中查找x或者x的后继:

前面介绍的bin_search()函数就是“在单调递增序列中查找x或者x的后继”的模板代码。

二分函数都是一摸一样的,测试数据可以改一下,看看能不能查找后继:

int main() {int n = 100;for(int i=0; i<n; i++) a[i]=2*i+2;    //赋值,数字2~200,偶数int test = 55;                        //查找55或55的后继int pos = bin_search(a,n,test);cout<<"test="<<a[pos];//56   55没有,只能找56了。
}

在单调递增序列中查找x或者x的前驱:

#include<bits/stdc++.h>
using namespace std;
int a[1000];
int bin_search2(int *a, int n, int x) {int left = 0, right = n;while (left < right) {int mid = left + (right-left + 1)/2 ;   //+1是为了确保在 left 和 right 之间的元素数量是奇数时,mid 会指向中间元素;当元素数量是偶数时,mid 会指向中间两个元素的右侧那个元素。//这样做的原因是,我们希望在存在重复元素时,mid 尽可能向右偏移,从而找到最右侧的那个等于或小于 x 的元素。if (a[mid] <= x)  left = mid;else  right = mid - 1;}return left;
}
int main() {int n = 100;for(int i=0; i<n; i++) a[i]=2*i+2;   //赋值,数字2~200,偶数int test = 55;                       //查找55或55的前驱int pos = bin_search2(a,n,test);cout<<"test="<<a[pos]; //54
}

整数二分例题

例题1.分巧克力

2017年(第八届)省赛,lanqiaoOJ题号99

先试试暴力法:从边长为1开始到最大边长d,每个值都试一遍,一直试到刚好够分的最大边长为止。编程思路:边长初始值d = 1,然后d = 2、3、4……一个一个地试 。

代码:

#include<bits/stdc++.h>
using namespace std;
int h[100010],w[100010];//多申请10个空间 
int n,k;
bool check(int d) {             //检查够不够分int num=0;for(int i=0; i<n; i++)  num += (h[i]/d)*(w[i]/d);//假如,将6×5的巧克力的长边(6个单位)和宽边(5个单位)分别除以2×2的小正方形的边长(2个单位)。//这样可以得到长边可以切出3个2×2的巧克力,宽边可以切出2个2×2的巧克力。//接着,将长边和宽边切出的巧克力块数相乘,即3(长边切出的块数)× 2(宽边切出的块数)= 6。所以,一块6×5的巧克力可以切出6块2×2的巧克力。if(num>=k) return true;     //够分else       return false;    //不够分
}
int main() {cin >>n>>k;for(int i=0; i<n; i++)  cin>>h[i]>>w[i];  //长宽各自存在各自的数组中 int d=1;                    //正方形边长while(1) {if(check(d))  d++;      //边长从1开始,一个一个地试else          break;}cout << d-1;return 0;     //暴力求解只能过75的测试数据 ,最后两个测试数据错了,暂时不知道什么原因
}

整数二分法求解:

#include<bits/stdc++.h>
using namespace std;
int n,k;
const int N=100010;
int h[N],w[N];
bool check(int d) {int num=0;for(int i=0; i<n; i++)  num += (h[i]/d)*(w[i]/d);if(num>=k) return true;      //够分else       return false;     //不够分
}
int main() {cin >> n >> k;for(int i=0; i<n; i++)   cin>>h[i]>>w[i];int L=1, R=N;                //R的初值是100010//第一种写法:while(L<R) {int mid=(L+R+1) / 2;      //除以2,向右取整      不会整数溢出,直接L+Rif(check(mid))  L=mid;   //新的搜索区间是右半部分,R不变,调整L=midelse            R=mid-1; //新的搜索区间是左半部分,L不变,调整R=mid–1}cout << L;//第二种写法:/*  while(L<R) {int mid=(L+R) / 2;        //除以2,向左取整   不会整数溢出,直接L+Rif(check(mid)) L=mid+1;  //新的搜索区间是右半部分,R不变,更新L=mid+1else           R=mid;    //新的搜索区间是左半部分,L不变,更新R=mid}cout << L-1;    */return 0;
}

实数二分

与整数二分相比,实数二分的编程就容易多了,不用考虑整数的取整问题。实数二分的模板代码如下。

const double eps = 1e-7;                    //精度。
while(right - left > eps) {                 double mid = left+(right-left)/2;if (check(mid)) right = mid;          //判定,然后继续二分,check(mid)为true执行此语句else            left  = mid;
}

相关文章:

蓝桥杯:C++二分算法

在基本算法中&#xff0c;二分法的应用非常广泛&#xff0c;它是一种思路简单、编程容易、效率极高的算法。蓝桥杯软件类大赛中需要应用二分法的题目很常见。 二分法有整数二分和实数二分两种应用场景 二分法的概念 二分法的概念很简单&#xff0c;每次把搜索范围缩小为上一…...

Leetcode刷题笔记题解(C++):83. 删除排序链表中的重复元素

思路&#xff1a;链表相关的问题建议就是画图去解决&#xff0c;虽然理解起来很容易&#xff0c;但就是写代码写不出来有时候&#xff0c;依次去遍历第二节点如果与前一个节点相等则跳过&#xff0c;不相等则遍历第三个节点 /*** Definition for singly-linked list.* struct …...

@ 代码随想录算法训练营第8周(C语言)|Day56(动态规划)

代码随想录算法训练营第8周&#xff08;C语言&#xff09;|Day56&#xff08;动态规划&#xff09; Day56、动态规划&#xff08;包含题目 ● 300.最长递增子序列 ● 674. 最长连续递增序列 ● 718. 最长重复子数组 &#xff09; 300.最长递增子序列 题目描述 给你一个整数…...

C# OpenCvSharp DNN Image Retouching

目录 介绍 模型 项目 效果 代码 下载 C# OpenCvSharp DNN Image Retouching 介绍 github地址&#xff1a;https://github.com/hejingwenhejingwen/CSRNet (ECCV 2020) Conditional Sequential Modulation for Efficient Global Image Retouching 模型 Model Properti…...

通过Docker Compose的方式在Docker中安装Maven环境

目前可以说 Docker 已经是在开发部署中成为主流&#xff0c;所以我们很多环境和工具都会安装在 Docker 容器中&#xff0c;Maven 环境是 SpringBoot 项目中最常用的依赖管理工具。当我们使用自动运维工具如 Ansible、Chef 、Puppet、Walle、Spug等&#xff09;管理和部署 Maven…...

Python实现线性逻辑回归和非线性逻辑回归

线性逻辑回归 # -*- coding: utf-8 -*- """ Created on 2024.2.20author: rubyw """import matplotlib.pyplot as plt import numpy as np from sklearn.metrics import classification_report from sklearn import preprocessing from sklearn…...

【软考】软件维护

目录 一、说明二、正确性维护三、适应性维护四、完善性维护五、预防性维护 一、说明 1.软件维护主要是根据需求变化或硬件环境的变化对应用程序进行部分或全部修改 2.修改时应充分利用源程序&#xff0c;修改后要填写程序修改登记表&#xff0c;并在程度变更通知书上写明新旧程…...

突破性创新:OpenAI推出Sora视频模型,预示视频制作技术的未来已到来!

一、前言 此页面上的所有视频均由 Sora 直接生成&#xff0c;未经修改。 OpenAI - Sora is an AI model that can create realistic and imaginative scenes from text instructions. 2024 年 2 月 16 日&#xff0c;OpenAI 发布 AI 视频模型 Sora&#xff0c;60 秒的一镜到底…...

【Web前端笔记10】CSS3新特性

10 CSS3新特性 &#xff11;、圆角 &#xff12;、阴影 &#xff08;&#xff11;&#xff09;盒阴影 &#xff13;、背景渐变 &#xff08;&#xff11;&#xff09;线性渐变&#xff08;主要掌握这种就可&#xff09; &#xff08;&#xff12;&#xff09;径向渐变 &…...

LabVIEW荧光显微镜下微管运动仿真系统开发

LabVIEW荧光显微镜下微管运动仿真系统开发 在生物医学研究中&#xff0c;对微管运动的观察和分析至关重要。介绍了一个基于LabVIEW的仿真系统&#xff0c;模拟荧光显微镜下微管的运动过程。该系统提供了一个高效、可靠的工具&#xff0c;用于研究微管与运动蛋白&#xff08;如…...

【Java面试】MQ(Message Queue)消息队列

目录 一、MQ介绍二、MQ的使用1应用解耦2异步处理3流量削峰4日志处理5消息通讯三、使用 MQ 的缺陷1.系统可用性降低:2.系统复杂性变高3.一致性问题四、常用的 MQActiveMQ:RabbitMQ:RocketMQ:Kafka:五、如何保证MQ的高可用?ActiveMQ:RabbitMQ:RocketMQ:Kafka:六、如何保…...

【安卓基础1】初识Android

&#x1f3c6;作者简介&#xff1a;|康有为| &#xff0c;大四在读&#xff0c;目前在小米安卓实习&#xff0c;毕业入职。 &#x1f3c6;安卓学习资料推荐&#xff1a; 视频&#xff1a;b站搜动脑学院 视频链接 &#xff08;他们的视频后面一部分没再更新&#xff0c;看看前面…...

08-静态pod(了解即可,不重要)

我们都知道&#xff0c;pod是kubelet创建的&#xff0c;那么创建的流程是什么呐&#xff1f; 此时我们需要了解我们k8s中config.yaml配置文件了&#xff1b; 他的存放路径&#xff1a;【/var/lib/kubelet/config.yaml】 一、查看静态pod的路径 [rootk8s231 ~]# vim /var/lib…...

PROBIS铂思金融破产后续:ASIC牌照已注销

2024年1月31日&#xff0c;PROBIS铂思金融的澳大利亚ASIC牌照 (AFSL 338241) 被注销《差价合约经纪商PROBIS宣布破产&#xff0c;澳大利亚金融服务牌照遭暂停》&#xff0c;这也就意味着&#xff0c;PROBIS铂思金融目前已经没有任何金融牌照。 值得注意的是&#xff0c;时至今日…...

数字世界的探索者:计算机相关专业电影精选推荐

目录 推荐计算机专业必看的几部电影 《黑客帝国》 《社交网络》 《乔布斯传》 《心灵捕手》 《源代码》 《盗梦空间》 《头号玩家》 《我是谁&#xff1a;没有绝对安全的系统》 《战争游戏》(WarGames) 《模仿游戏》(The Imitation Game) 《硅谷》(Silicon Valley) …...

Spring Boot项目中TaskDecorator的应用实践

一、前言 TaskDecorator是一个执行回调方法的装饰器&#xff0c;主要应用于传递上下文&#xff0c;或者提供任务的监控/统计信息&#xff0c;可以用于处理子线程与主线程间数据传递的问题。 二、开发示例 1.自定义TaskDecorator import org.springframework.core.task.Task…...

511. 游戏玩法分析 I

文章目录 题意思路代码 题意 题目链接 统计每个用户第一次登陆平台时间 思路 代码 select player_id, min(event_date) as first_login from Activity group by player_id;...

大模型训练流程(三)奖励模型

为什么需要奖励模型 因为指令微调后的模型输出可能不符合人类偏好&#xff0c;所以需要利用强化学习优化模型&#xff0c;而奖励模型是强化学习的关键一步&#xff0c;所以需要训练奖励模型。 1.模型输出可能不符合人类偏好 上一篇讲的SFT只是将预训练模型中的知识给引导出来…...

替换if...else的锦囊妙计

目录 前言 一、又臭又长的if...else 二、消除if...else的锦囊妙计 1、使用注解 2、动态拼接名称 3、模板方法判断 4.策略工厂模式 5.责任链模式 6、其他的消除if...else的方法 1.根据不同的数字返回不同的字符串 2.集合中的判断 3.简单的判断 4.spring中的判断 原文…...

新建一个flask项目

在Flask中创建一个新的项目&#xff0c;您可以遵循以下步骤&#xff1a; 确保您已经安装了Python环境。如果还未安装Flask&#xff0c;可以通过pip来安装&#xff1a; pip install flask创建一个新的文件夹作为您的项目文件夹&#xff0c;例如myflaskapp&#xff1a; mkdir …...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...

解读《网络安全法》最新修订,把握网络安全新趋势

《网络安全法》自2017年施行以来&#xff0c;在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂&#xff0c;网络攻击、数据泄露等事件频发&#xff0c;现行法律已难以完全适应新的风险挑战。 2025年3月28日&#xff0c;国家网信办会同相关部门起草了《网络安全…...

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分&#xff1a;机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域&#xff0c;衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标&#xff0c;自2002年由IBM的Kishore Papineni等人提出以来&#xff0c;…...

离线语音识别方案分析

随着人工智能技术的不断发展&#xff0c;语音识别技术也得到了广泛的应用&#xff0c;从智能家居到车载系统&#xff0c;语音识别正在改变我们与设备的交互方式。尤其是离线语音识别&#xff0c;由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力&#xff0c;广…...