蓝桥杯: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~100
	int 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+R
		if(check(mid))  L=mid;   //新的搜索区间是右半部分,R不变,调整L=mid
		else            R=mid-1; //新的搜索区间是左半部分,L不变,调整R=mid–1
	}
	cout << L;
	//第二种写法:
	/*  while(L<R) {
	        int mid=(L+R) / 2;        //除以2,向左取整   不会整数溢出,直接L+R
	        if(check(mid)) L=mid+1;  //新的搜索区间是右半部分,R不变,更新L=mid+1
	        else           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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux POSIX信号量 线程池

Linux POSIX信号量 线程池 一. 什么是POSIX信号量&#xff1f;二. POSIX信号量实现原理三. POSIX信号量接口函数四. 基于环形队列的生产消费模型五. 线程池 一. 什么是POSIX信号量&#xff1f; POSIX信号量是一种用于同步和互斥操作的机制&#xff0c;属于POSIX&#xff08;Po…

WINCC如何新增下单菜单,切换显示页面

杭州工控赖工 首先我们先看一下&#xff0c;显示的效果&#xff0c;通过下拉菜单&#xff0c;切换主显示页面。如图一&#xff1a; 图1 显示效果 第一步&#xff1a; 通过元件新增一个组合框&#xff0c;见图2&#xff1b; 组合框的设置&#xff0c;设置下拉框的长宽及组合数…

[java基础揉碎]数组 值拷贝和引用拷贝的赋值方式

目录 数组的介绍 为什么有数组 数组的三种使用方式 动态初始化: 静态初始化: 数组使用注意事项和细节 值拷贝和引用拷贝的赋值方式 数组反转: 数组拷贝: 数组的介绍 数组可以存放多个同一类型的数据。数组也是一种数据类型&#xff0c;是引用类型。 即&#xff1a;数组…

解决ubuntu登录密码问题

解决ubuntu登录密码问题 不要随便删除密码&#xff0c;不要随便改密码&#xff0c;很容导致密码过期&#xff0c;或者密码无效。参考了很多人的做法&#xff0c;都没有得到解决。下面的过程&#xff0c;够详细了&#xff0c;我就是这么搞好的。 1、重启虚拟机&#xff0c;不停…

Ubuntu忘记登录密码重置步骤

Ubuntu忘记登录密码重置步骤 1.开机界面长按shitf键&#xff0c;进入grub&#xff0c;并选择Advanced options for ubuntu&#xff0c;按下回车 2.选择一个较新版本的recovery mode&#xff0c;按下回车 3.会跑一些数据&#xff0c;等待跑完后会出现下面的界面&#xff0c;选择…

SG7050VEN(晶体振荡器SPXO)输出:LVDS低相位抖动

SG7050VEN 提供了从25 MHz到500 MHz的宽广频率范围&#xff0c;2.5V和3.3V供电电压,可以轻松集成到各种电源中&#xff0c;7.0 5.0 1.5 mm 的封装&#xff0c;LVDS输出已成为高速数据传输的首选&#xff0c;它提供了低功耗和高速率的优势&#xff0c;同时还能最小化电磁干扰。…

基于BP算法的SAR成像matlab仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 BP算法的基本原理 4.2 BP算法的优点与局限性 5.完整工程文件 1.课题概述 基于BP算法的SAR成像。合成孔径雷达&#xff08;SAR&#xff09;是一种高分辨率的雷达系统&#xff0c;能够在各种天气和光…

幻兽帕鲁服务器创建私服教程(新版教程更简单)

幻兽帕鲁官方服务器不稳定&#xff1f;自己搭建幻兽帕鲁服务器&#xff0c;低延迟、稳定不卡&#xff0c;目前阿里云和腾讯云均推出幻兽帕鲁专用服务器&#xff0c;腾讯云直接提供幻兽帕鲁镜像系统&#xff0c;阿里云通过计算巢服务&#xff0c;均可以一键部署&#xff0c;鼠标…

Linux第58步_备份busybox生成rootfs根文件系统

备份busybox生成rootfs根文件系统 打开终端 输入“ls回车” 输入“cd linux/回车” 输入“ls回车”&#xff0c;产看“linux”目录下的文件和文件夹 输入“cd nfs/回车”&#xff0c;切换到“nfs”目录 输入“ls回车”&#xff0c;产看“nfs”目录下的文件和文件夹 输入…

大模型专题:大模型赋能智慧办公评测报告

今天分享的是大模型系列深度研究报告&#xff1a;《大模型专题&#xff1a;大模型赋能智慧办公评测报告》。 &#xff08;报告出品方&#xff1a;国家工业信息安全发展研究中心人工智能所&#xff09; 报告共计&#xff1a;34页 来源&#xff1a;人工智能学派 评测背景 当…

Deep learning学习笔记

lec 1&#xff1a;Regression 1.5 Linear neural networks for regression线性神经网络的回归 I parameterizing output layer, I handling data, I specifying loss function, I training model. 浅层网络包括线性模型&#xff0c;其中包含了许多经典的统计预测方法&…

javaweb学习day03(JS+DOM)

一、javascript入门 1 官方文档 地址: https://www.w3school.com.cn/js/index.asp离线文档: W3School 离线手册(2017.03.11 版).chm 2 基本说明 JavaScript 能改变 HTML 内容&#xff0c;能改变 HTML 属性&#xff0c;能改变 HTML 样式 (CSS)&#xff0c;能完成 页面的数据…

阿里云服务器租用价格2024年新版活动报价和租用收费标准

2024年最新阿里云服务器租用费用优惠价格表&#xff0c;轻量2核2G3M带宽轻量服务器一年61元&#xff0c;折合5元1个月&#xff0c;新老用户同享99元一年服务器&#xff0c;2核4G5M服务器ECS优惠价199元一年&#xff0c;2核4G4M轻量服务器165元一年&#xff0c;2核4G服务器30元3…

macOS 安装 conda

macOS 安装 conda 安装 conda参考 Conda是一个开源的软件包管理系统和环境管理系统&#xff0c;用于安装和管理软件包和其依赖项。 安装 conda mkdir miniconda3 cd miniconda3 bash Miniconda3-latest-MacOSX-x86_64.sh$ conda list参考 macOS 安装 conda开始使用conda

XSS数据接收平台

一.使用xss数据接收平台的好处&#xff1a; 正常执行反射型xss和存储型xss&#xff0c;反射型xss在执行poc时&#xff0c;会直接在页面弹出执行注入的poc代码&#xff1b;存储型则是&#xff0c;在将poc代码注入用户的系统中后&#xff0c;用户访问有存储型xss的地方&#xff…

前端工程化面试题 | 12.精选前端工程化高频面试题

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

51单片机项目(31)——基于51单片机篮球计分器的proteus仿真

1.功能设计 可以通过两组按键&#xff0c;控制两个队伍的加减分&#xff0c;加分设置有&#xff0b;1分按键&#xff0c;&#xff0b;2分按键&#xff0c;&#xff0b;3分按键。减分设置有&#xff0d;1分按键。 设置有开始/暂停按键&#xff0c;按下开始&#xff0c;数码管便开…

LeetCode Python - 20.有效的括号

目录 题目答案运行结果 题目 给定一个只包括 ‘(’&#xff0c;‘)’&#xff0c;‘{’&#xff0c;‘}’&#xff0c;‘[’&#xff0c;‘]’ 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。左括号必须以正…

php基础学习之作用域和静态变量

作用域 变量&#xff08;常量&#xff09;能够被访问的区域&#xff0c;变量可以在常规代码中定义&#xff0c;也可以在函数内部定义 变量的作用域 在 PHP 中作用域严格来说分为两种&#xff0c;但是 PHP内部还定义一些在严格意义之外的一种&#xff0c;所以总共算三种—— 局部…

人工智能专题:2024亚太地区生成式人工智能应用与监管报告

今天分享的是人工智能系列深度研究报告&#xff1a;《人工智能专题&#xff1a;2024亚太地区生成式人工智能应用与监管报告》。 &#xff08;报告出品方&#xff1a;德勤&#xff09; 报告共计&#xff1a;20页 来源&#xff1a;人工智能学派 知识更新&#xff1a;了解传统…