2022-11-03 Acwing每日一题
本系列所有题目均为Acwing课的内容,发表博客既是为了学习总结,加深自己的印象,同时也是为了以后回过头来看时,不会感叹虚度光阴罢了,因此如果出现错误,欢迎大家能够指出错误,我会认真改正的。同时也希望文章能够让你有所收获,与君共勉!
今天主要学习二分法查找,二分主要分为两种类型,一种是整数二分查找,一种是浮点数二分查找。先看看整数二分,其模板如下:
整数二分
//查找左边界 SearchLeft 简写SL
int SL(int l, int r)
{
while (l < r)
{
int mid = l + r >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
return l;
}
//查找右边界 SearchRight 简写SR
int SR(int l, int r)
{
while (l < r)
{
int mid = l + r + 1 >> 1; //需要+1 防止死循环
if (check(mid)) l = mid;
else r = mid - 1;
}
return r;
}
最有效的方式就是通过题目来理解二分。
数的范围
给定一个按照升序排列的长度为 n 的整数数组,以及 q 个查询。
对于每个查询,返回一个元素 k 的起始位置和终止位置(位置从 0 开始计数)。
如果数组中不存在该元素,则返回 -1 -1。
输入格式
第一行包含整数 n 和 q,表示数组长度和询问个数。
第二行包含 n 个整数(均在 1∼10000 范围内),表示完整数组。
接下来 q 行,每行包含一个整数 k,表示一个询问元素。
输出格式
共 q 行,每行包含两个整数,表示所求元素的起始位置和终止位置。
如果数组中不存在该元素,则返回 -1 -1。
数据范围
1≤n≤100000
1≤q≤10000
1≤k≤10000
输入样例:
6 3
1 2 2 3 3 4
3
4
5
输出样例:
3 4
5 5
-1 -1
个人解析
引用自[https://www.acwing.com/solution/content/107848/]
我们可以理解为我们只需要找到这个数组成的区间左端点和右端点即可知道这段区间的位置,而查找左端点和右端点就可以使用二分来快速的查找(当然暴力也可以做)。
1.我们先考虑查找左端点时所需要的条件, 比较a[mid]
与x
,什么时候这个条件成立时能缩小右端点r = mid
,反之,条件不成立时,缩小左端点l = mid+1
我们可以想到,当a[mid]
比x
大时,需要往左边寻找,当a[mid]
比x
小时,需要往右边寻找,最终找到结果时一定有l==r
(因为循环条件l<r
)
2.再来考虑右端点的条件,参考查找左端点,我们需要尽可能地改变左端点l = mid
,因此结论为,当a[mid]
比x
要小时,要往右边寻找,当a[mid]
比x
要大时,要往左边寻找。
3.需要注意的是,模板中找左端点时mid = l + r >> 1
,而找右端点时mid = l+r+1 >> 1
,我们怎么来分辨什么时候+1,什么时候不+1呢,并且很多题目都不会明确告诉你要求区间端点。这时我们可以看条件成立时Check(a[mid],x)
的缩小区间这一步,如果为r=mid
就不需要+1,如果为l=mid
就需要+1。
综上,这道题算是完成了。
代码实现
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int q[100000];
int main(void){
int n,m;
cin >> n >> m;
for(int i=0; i < n ; ++i) cin >> q[i];
while(m--){
int l = 0,r = n-1,x;
cin >> x;
// 1.找到区间的左端,满足条件(x将区间分为两段,要找右端的最左边,满足x右端数的条件往左边缩小范围)
while( l<r ){
int mid = l + (r-l)/2;
if(q[mid] >= x){
r = mid;
}
else{
l = mid + 1;
}
}
if(q[l] != x){
cout << "-1" << " " << "-1" <<endl;
}
else{
cout << l << ' ';
l = 0 , r = n-1;
// 满足x左端数的条件往右边缩小,找最大值,注意往右边缩小范围时要+1防止向下取整
while(l<r){
int mid = (l+r+1)/2;
if(q[mid] <= x){
l = mid;
}
else{
r = mid-1;
}
}
cout << r << endl;
}
}
return 0;
}
力扣上跟这道题很像的二分:点击这里
浮点数二分
这就比较简单了,不需要考虑找边界,就是找一个浮点数呗,因此退出循环的条件也变成了r-l
小于很小的数时才会退出。
模板为:
bool check(double x) {/* ... */} // 检查x是否满足某种性质
double bsearch_3(double l, double r)
{
const double eps = 1e-6; // eps 表示精度,取决于题目对精度的要求
while (r - l > eps)
{
double mid = (l + r) / 2;
if (check(mid)) r = mid;
else l = mid;
}
return l;
}
这道浮点数二分的题就是模板:数的三次根。
2022-11-03 Acwing每日一题的更多相关文章
- [ 10.03 ]CF每日一题系列—— 534B贪心
Descripe: 贪心,贪在哪里呢…… 给你初始速度,结尾速度,行驶秒数,每秒速度可变化的范围,问你行驶秒数内最远可以行驶多少距离 Solution: 贪心,我是否加速,就是看剩下的时间能不能减到原 ...
- CISP/CISA 每日一题 11
CISA 每日一题(答) 一个合理建造的数据仓库应当支持下列三种基本的查询格式: 1.向上溯源和向下溯源——向上溯源是对数据进行总计:向下溯源是将数据进行细化: 2.交叉溯源——通过通用属性访问数据仓 ...
- 老男孩IT教育-每日一题汇总
老男孩IT教育-每日一题汇总 第几天 第几周 日期 快速访问链接 第123天 第二十五周 2017年8月25日 出现Swap file….already exists以下错误如何解决? 第122天 2 ...
- 【Java每日一题】20161122
package Nov2016; import java.util.ArrayList; import java.util.Iterator; public class Ques1122 { publ ...
- PL/SQL Challenge 每日一题:2014-3-14 11gR2中带RELIES_ON子句的RESULT_CACHE函数
PL/SQL Challenge 每日一题:2014-3-14 11gR2中带RELIES_ON子句的RESULT_CACHE函数 最先答对且答案未经编辑的puber将获得纪念章一枚(答案不可编辑但可 ...
- CISP/CISA 每日一题 五
CISA 每日一题(答) 信息系统审计师要确认系统变更程序中的: 1.变更需求应有授权.优先排序及跟踪机制: 2.日常工作手册中,明确指出紧急变更程序: 3.变更控制程序应同时为用户及项目开发组认可: ...
- [每日一题]ES6中为什么要使用Symbol?
关注「松宝写代码」,精选好文,每日面试题 加入我们一起学习,day day up 作者:saucxs | songEagle 来源:原创 一.前言 2020.12.23日刚立的flag,每日一题,题目 ...
- [每日一题]面试官问:谈谈你对ES6的proxy的理解?
[每日一题]面试官问:谈谈你对ES6的proxy的理解? 关注「松宝写代码」,精选好文,每日一题 作者:saucxs | songEagle 一.前言 2020.12.23 日刚立的 flag,每日一 ...
- 【js】Leetcode每日一题-完成所有工作的最短时间
[js]Leetcode每日一题-完成所有工作的最短时间 [题目描述] 给你一个整数数组 jobs ,其中 jobs[i] 是完成第 i 项工作要花费的时间. 请你将这些工作分配给 k 位工人.所有工 ...
- 【JavaScript】Leetcode每日一题-青蛙过河
[JavaScript]Leetcode每日一题-青蛙过河 [题目描述] 一只青蛙想要过河. 假定河流被等分为若干个单元格,并且在每一个单元格内都有可能放有一块石子(也有可能没有). 青蛙可以跳上石子 ...
随机推荐
- 058_末晨曦Vue技术_过渡 & 动画之过渡的类名
进入/离开 & 列表过渡 点击打开视频讲解更加详细 概述 Vue 在插入.更新或者移除 DOM 时,提供多种不同方式的应用过渡效果.包括以下工具: 在 CSS 过渡和动画中自动应用 class ...
- 安装docker-compose--翻译
Install Docker Compose 译文 安装 Docker Compose 你可以在macOS.Windows.64-bit Linux上运行 Compose 前提条件 Docker Co ...
- mysql8.0及以上修改Root密码
ALTER user 'root'@'localhost' IDENTIFIED BY 'Cliu123#' //1.不需要flush privileges来刷新权限. //2.密码要包含大写字母,小 ...
- Centos7下安装postgresql(tar包形式安装)
Centos7下安装postgresql(tar包形式安装) 1.官网下载地址: https://www.postgresql.org/ftp/source/ 2.将下载来tar包上传到linux服务 ...
- Windows 10中蓝牙鼠标连接
最近遇到了一个问题,Windows 10中的蓝牙鼠标无法连接. 在添加蓝牙鼠标的时候系统提示输入PIN码.通常在蓝牙连接两个系统的时候会需要双方输入PIN码来确认身份,但是鼠标这种设备是没有地方显示P ...
- 接入Twitter和Facebook分享踩坑记录
准备工作 1.首先需要在HTML的head添加下述meta标签内容,在分享时,Twitter和Facebook会爬取该网站页面的meta内容,然后生成分享卡片. 2.按照下述配置完成后,需要把内容发布 ...
- Object.keys的‘诡异’特性,你值得收藏!
先从'诡异'的问题入手 例1: 纯Number类型的属性 const obj = { 1: 1, 6: 6, 3: 3, 2: 2 } console.log('keys', Object.keys( ...
- CentOS无法识别NTFS格式U盘完美解决方案
问题描述:CentOS上无法识别NTFS格式的U盘 解决方案: # 进入yum目录 cd /etc/yum.repos.d # 下载阿里的epel wget http://mirrors.aliyun ...
- Css3中自适应布局单位vh、vw
视口单位(Viewport units) 什么是视口? 在桌面端,视口指的是在桌面端,指的是浏览器的可视区域:而在移动端,它涉及3个视口:Layout Viewport(布局视口),Visual Vi ...
- C#-7 结构和枚举
一 什么是结构 结构是程序员定义的数据类型,有数据成员和函数成员,和类非常类似. 类是引用类型,而结构是值类型: 结构和类一样可以实现接口: 结构是隐式密封的,不能被派生: 结构类型的变量不能为nul ...