二分/二分查找(整数二分详解+拓展浮点二分)

先上题目

在一个有序数组中,查找x所在的下标。

输入
第一行两个整数n和m。

第二行n个数,表示有序的数列。

接下来m行,每行一个整数x,表示一个询问的数。

输出
对于每个询问如果x在数列中,输出下标。否则输出-1

样例
输入 1
5 3
3 4 5 7 9
7
3
8
输出 1
4
1
-1
提示
对于100%的数据

n和m的范围[0,10^5];

x和数列中的元素范围[-10^6, 10^6];

数列中的任意两个元素都不相同。

【分析】很明显这是一道查找题,我们直接for一遍就行。但是,如果真能这样那就没有二分存在的必要了,for一遍的最坏的时间复杂度是O(m*n),就是O(10^5 * 10^5),这。。。确定不会超时吗,所以就到了我们今天的主题二分上场了

何为二分?

二分就像他的名字,是分一半,然后再分一半……,(如图)
在这里插入图片描述
二分是一种分治的思想,二分查找也是。二分的工作原理就是每次取中间,然后判断+调整,
无限逼近最终答案。
当然二分的前提是得有序,无论什么,都要有序
下面是二分的伪代码

void points(){int l=1,r=n,best=-1;   //左   右    答案while(l<=r)    //范围    当越过范围时就是答案{int mid=(l+r)/2;if(judge()){  //条件判断l=mid+1;   //逼近best=mid; //保存答案}else{r=mid-1;  //逼近}}
}

没错就这么短,却步步都是精髓,也非常实用,而且他的时间复杂度是 O(log n)

整数二分经典例题

既然已经理解二分了,那就先来个二分查找助助兴
在一个有序数组中,查找x所在的下标。

输入
第一行两个整数n和m。

第二行n个数,表示有序的数列。

接下来m行,每行一个整数x,表示一个询问的数。

输出
对于每个询问如果x在数列中,输出下标。否则输出-1

样例
输入 1
5 3
3 4 5 7 9
7
3
8
输出 1
4
1
-1
提示
对于100%的数据

n和m的范围[0,10^5];

x和数列中的元素范围[-10^6, 10^6];

数列中的任意两个元素都不相同。
【分析】为什么是刚开始的题目?咳咳。。。这不重要。这是一道简单的二分查找题,而且已经给出是有序数组,所以只需套下伪代码。不过仍需注意,二分只是逼近,并不是准确,所以二分时还要看情况特判。

#include<bits/stdc++.h>
using namespace std;
int n,m;
const int N=1e5+10;
int a[N],d; 
int find(int x){int l=1,r=n,best=-1;while(l<=r){   //二分int mid=(l+r)/2;//取中间if(a[mid]>=x){   //大了或等于r=mid-1;   //变为前半部分best=mid;  //保存}else{   //小了l=mid+1;   //变为后半部分}}if(a[best]!=x) return -1;   //特判,万一没有return best;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
while(m--){cin>>d;cout<<find(d)<<"\n";
}return 0;
}

第二题

给你一个有序的整数序列,有一系列的询问,每次询问给出一个整数num,你需要回答序列中第一个等于num的位置,最后一个等于num的位置,第一个大于num的位置,如果相应的位置不存在,就输出-1

输入
第一行输入一个整数n (1<=n<=100000)

第二行输入n个整数ai, (1<=ai<=100000)

第三行输入一个整数m,表示询问的个数 (1<=m<=100000)

接下来m行每行一个整数bi,(0<=bi<=100000)

输出
对于每个询问输出三个整数

样例
输入 1复制
10
1 3 5 7 7 7 7 9 10 11
6
1
0
7
8
11
12
输出 1复制
1 1 2
-1 -1 1
4 7 8
-1 -1 8
10 10 -1
-1 -1 -1
【分析】简单又不太简单的经典二分(当然如果你用STL里的 lowerbound和upperbound我也没办法),要注意,这次的逼近,得分情况了,如果是求第一个等于num,就往前逼近,求最后一个就往后逼近,第一个大于num就不要保存等于了,保存大于,且往后逼近

#include<bits/stdc++.h>
using namespace std;
const int N=100050;
int n,a[N],m,b;
int find1(int x)     //找第一个等于
{int l=1,r=n,best=-1;while(l<=r){int mid=(l+r)/2;if(a[mid]>=x){r=mid-1;best=mid;}else{l=mid+1;}}if(a[best]!=x) return -1;return best;
}
int find2(int x){   //最后一个等于int l=1,r=n,best=-1;while(l<=r){int mid=(l+r)/2;if(a[mid]<=x){best=mid;l=mid+1;}else{r=mid-1;}}if(a[best]!=x) return -1;return best;
}
int find3(int x){   //第一个大于if(a[1]>x) return 1;   //特殊情况if(a[n]<x) return -1;int l=1,r=n,best=-1;while(l<=r){int mid=(l+r)/2;if(a[mid]>x){   //不保存等于了r=mid-1;best=mid;}else{l=mid+1;}}return best;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
cin>>m;
while(m--){cin>>b;int k=find2(b);cout<<find1(b)<<" "<<k<<" "<<find3(b)<<"\n";
}return 0;
}

第三题(前方高能!!!)
【题目描述】
农夫 John 建造了一座很长的畜栏,它包括N(2≤N≤100,000)
个隔间,这些小隔间依次编号为x1,…,xN(0≤xi≤1,000,000,000)
. 但是,John的C(2≤C≤N)
头牛们并不喜欢这种布局,而且几头牛放在一个隔间里,他们就要发生争斗。为了不让牛互相伤害。John决定自己给牛分配隔间,使任意两头牛之间的最小距离尽可能的大,那么,这个最大的最小距离是什么呢

【输入】
第一行:空格分隔的两个整数N
和C;
第二行—第N+1行:i+1行指出了xi的位置。

【输出】
一个整数,最大的最小值。

【输入样例】
5 3
1 2 8 4 9
【输出样例】
3
【提示】
把牛放在1,4,8
这样最小距离是3

【分析】这一题还是有难度,首先得知道怎么办,二分!为什么?我们想想暴力是不是能做,但数据范围太大,那只能二分了。然后主要不知道二分啥,那我们想想,除了二分位置,距离,这题还能二分啥,二分位置也解不出来,只能二分距离,且是最大距离,所以这题有了:
1.排序数组不能忘
2.二分最大距离
3. 无限逼近

#include<bits/stdc++.h>
using namespace std;
int n,c;
const int N=100050;
long long x[N];
bool judge(long long mid)   //判断这个距离能否符合要求
{int cnt=1;long long th=x[1];   //上一个房屋for(int i=2;i<=n;i++){if(x[i]-th>=mid){    //距离是否大于midth=x[i];   //更换上一个房屋cnt++;     //房屋++}}return cnt>=c;   //符合要求
}
int main(){
cin>>n>>c;
for(int i=1;i<=n;i++) cin>>x[i];
sort(x+1,x+n+1);  //排序
long long l=1,r=1e10,best=-1;
while(l<=r){  //二分最大距离long long mid=(l+r)/2;if(judge(mid)){   //判断l=mid+1;   //可以就继续best=mid;   //保存}else{r=mid-1;  //距离太大,缩小}
}
cout<<best;return 0;
}

拓展浮点二分

浮点二分相比于普通二分难比较了,而且也不能加1,减1了
这里给大家整理了下注意事项
1.浮点比较得用eps(其实就是0,为了防止精度不够,通常要射,如1e-6,就是把0保留了6位小数),或者限定次数
2.浮点二分通常用bool函数区比较,直接的话容易爆精度
3.浮点二分的精度设的大些,方爆精度的
好的有请例题
在x轴上有n个人,每个人有一个移动速度 v1,v2,v3…vn, 现在需要找一个地方让大家聚到一起开会,问你最少需要多少时间才可以让所有人都到达同一个点

输入
第一行输入一个整数n

第二行输入n个整数

x1,x2,x3…xn 表示每个人初始的位置

第三行输入n个整数

v1,v2,v3…vn表示每个人的移动速度

输出
输出一个浮点数,保留五位小数

样例
输入 1复制
3
7 1 3
1 2 1
输出 1复制
2.00000
输入 2复制
10
2 3 5 7 11 13 17 19 23 29
6 5 4 3 2 1 2 3 4 5
输出 2复制
2.75000
2≤n≤60000,1≤x i​ ,v i ≤10 ^ 9
【分析】这题我直接说了,是二分时间,至于为什么大家可以自己思考。二分时间的话这题就简单了

#include<bits/stdc++.h>
using namespace std;
const int N=60005;
int n,x[N],v[N];
const double eps=1e-6;
bool judge(double mid){double mi=-1e18;double mx=1e18;for(int i=1;i<=n;i++){double l=x[i]*1.0-v[i]*mid;   //最小的位置double r=x[i]*1.0+v[i]*mid;    //最大的位置if(l-mi>eps) mi=l;if(r-mx<-eps) mx=r;}if(mx-mi>=eps) return true;return false;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&x[i]);
for(int i=1;i<=n;i++) scanf("%d",&v[i]);
double l=1,r=1e9,best=-1;
int step=50;
while(step--){//二分次数double mid=(l+r)/2;if(judge(mid)){r=mid-1;best=mid;}else{l=mid+1;}
}
printf("%.5f",best);return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Linux网络编程: IP协议详解

一、TCP/IP五层模型 物理层&#xff08;Physical Layer&#xff09;&#xff1a;物理层是最底层&#xff0c;负责传输比特流&#xff08;bitstream&#xff09;以及物理介质的传输方式。它定义了如何在物理媒介上传输原始的比特流&#xff0c;例如通过电缆、光纤或无线传输等。…

2024年腾讯云2核4G服务器够用吗?性能测评

腾讯云轻量2核4G5M带宽服务器支持多少人在线访问&#xff1f;5M带宽下载速度峰值可达640KB/秒&#xff0c;阿腾云以搭建网站为例&#xff0c;假设优化后平均大小为60KB&#xff0c;则5M带宽可支撑10个用户同时在1秒内打开网站&#xff0c;并发数为10&#xff0c;经阿腾云测试&a…

第三门课:结构化机器学习项目-机器学习策略

文章目录 1 机器学习策略一1.1 为什么是ML策略&#xff1f;1.2 正交化1.3 单一数字评估指标1.4 满足和优化指标1.5 训练、开发及测试集划分1.6 开发集和测试集的大小1.7 什么时候改变开发、测试集和指标&#xff1f;1.8 为什么是人的表现&#xff1f;1.9 可避免偏差1.10 理解人…

【编程项目开源】微信飞机大战(鸿蒙版)

目标 仿微信飞机大战 效果 开发工具 下载DevEco Studio 工程截图 开源地址 https://gitee.com/lblbc/plane_game/tree/master/PlaneGame_hongmeng_ArkTS 关于 厦门大学计算机专业|华为八年高级工程师 专注《零基础学编程系列》 http://lblbc.cn/blog 包含&#xff1a;Ja…

前端Prettier 插件的使用配置(详细)

各个参数代表的意思:printWidth&#xff1a;每行代码的最大长度限制。 tabWidth&#xff1a;选项用于控制制表符的宽度。 useTabs&#xff1a;指定是否使用制表符代替空格。 semi&#xff1a;指定是否在语句的末尾添加分号。 singleQuote&#xff1a;指定是否使用单引号或双引号…

操作系统系列学习——一个实际的schedule函数

文章目录 前言一个实际的schedule函数 前言 一个本硕双非的小菜鸡&#xff0c;备战24年秋招&#xff0c;计划学习操作系统并完成6.0S81&#xff0c;加油&#xff01; 本文总结自B站【哈工大】操作系统 李治军&#xff08;全32讲&#xff09; 老师课程讲的非常好&#xff0c;感…

Java后端面试经验分享,~纯分享

本文将从面试、工作、学习三个方面分享最近面试的一些心得以及以后发展的一些规划&#xff0c;仅供参考&#xff0c;哈哈&#xff0c;毕竟本人也很菜&#xff0c;因为菜才要多学习。一会儿也会分享两本Java面试题库&#xff08;题库是b站大学找的&#xff0c;一会儿我也会分享出…

如何将Git拉取项目后,将SSH验证方式修改为HTTPS?

首先在打开项目所在位置的Git BashGUI 查找当前的远程仓库URL&#xff1a; 打开终端或命令提示符&#xff0c;导航到你的项目目录&#xff0c;并使用以下命令查看当前配置的远程仓库URL&#xff1a; git remote -v这会显示如下格式的输出&#xff1a; origin gitgithub.com:用…

python自动化之pytest框架以及数据驱动(第五天)

1.pytest框架需要遵循的规则 &#xff08;1&#xff09;.py 测试文件必须以test 开头(或者以 test结尾) &#xff08;2&#xff09;测试类必须以Test开头&#xff0c;并且不能有 init 方法 &#xff08;3&#xff09;测试方法必须以test 开头 &#xff08;4&#xff09;断言…

电大搜题:开启学习新时代

身处信息化时代&#xff0c;学习的方式已经发生了巨大的变革。在这个多元化的学习环境中&#xff0c;传统的学习模式已经无法满足现代学习者的需求。然而&#xff0c;电大搜题应运而生&#xff0c;为学习者提供了一个高效、便捷的学习途径。 电大搜题&#xff0c;作为黑龙江开…

Java课程实验—作业二

题目一 代码 import java.util.*;public class Main {public static void main(String[] args){Scanner inputnew Scanner(System.in);String strinput.nextLine();//nextLine()方法遇到回车结束输入&#xff0c;next()遇到空格int[]anew int[10];//用来计数a[0]-1;for(int i0…

Java复习01 集合概念

Java复习01 集合 在Java中&#xff0c;集合&#xff08;Collections&#xff09;是一种用来存储一组对象的结构。想象一下有一个装东西的箱子&#xff0c;这个箱子可以装很多不同类型的东西&#xff0c;例如书、DVD或者玩具。Java的集合也是这样&#xff0c;但是它专门用来装载…

更安全的C gets()和str* 以及fgets和strcspn的用法

#include <stdio.h>int main() {char *str;gets(str);puts(str);return(0); }可以说全是错误 首先char *str没有指向一个分配好的地址&#xff0c;就直接读入&#xff0c;危险 ps: 怎么理解char *str "Hello World" 是将一个存储在一个只读的数据段中字符串常…

java算法第25天 | ● 216.组合总和III ● 17.电话号码的字母组合

这两道题都是基于回溯的基本问题。 216.组合总和III 这道题是77.组合问题的变体&#xff0c;只不过终止条件多了一个和等于n。 class Solution {List<List<Integer>> resnew ArrayList<>();List<Integer> pathnew ArrayList<>();public List&l…

c++算法学习笔记 (8) 树与图部分

1.树与图的存储 &#xff08;1&#xff09;邻接矩阵 &#xff08;2&#xff09;邻接表 // 链式前向星模板&#xff08;数组模拟&#xff09; #include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N 100010, M …

ABC345(A-C)

A - Leftrightarrow(100 points) 语法题&#xff0c;输入一个字符串&#xff0c;判断是否是&#xff1a;的样式&#xff0c;输入后只需判断是第一个和最后一个字符是否分别为">"和"<",再判断中间是否都是""即可。 #include<bits/stdc…

pta上的几个例题

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

双向SSM: Vision Mamba Encoder

文章目录 Vision Mamba Encoder初始化输入映射序列变换参数映射BC参数映射delta参数映射 SSM参数初始化A , D矩阵初始化delta参数初始化 双向SSM初始化参数初始化 前向输入映射fast_pathuse_fast_pathno use_fast_path 双向SSMv1前向后向 v2前向后向 Vision Mamba Encoder Vis…

解决游戏程序一运行就退出的问题

正文&#xff1a; 在游戏开发过程中&#xff0c;我们可能会遇到程序一运行就立即退出的情况。这种情况通常是由于程序中的某些逻辑错误或初始化问题导致的。 下面我们将分析可能的原因&#xff0c;并提供一些解决方案。 目录 正文&#xff1a; 原因分析&#xff1a; 解决方案…

AI健身教练-引体向上-俯卧撑计数-仰卧起坐姿态估计-康复训练姿态识别-姿态矫正

在AI健身应用中&#xff0c;通过关键点检测技术可以实现对用户动作的精准捕捉和分析&#xff0c;从而进行统计计数和规范性姿态识别。 统计计数&#xff1a;比如在做瑜伽、健身操等运动时&#xff0c;系统可以通过对人体关键点&#xff08;如手部、脚部、关节等&#xff09;的…