二分练习题2 查找大于等于x的最小元素 题解
题目描述
现在告诉你一个长度为 \(n\) 的有序数组 \(a_1, a_2, ..., a_n\) ,以及 \(q\) 次询问,每次询问会给你一个数 \(x\) ,对于每次询问,你需要输出数组 \(a\) 中大于等于 \(x\) 的最小元素。
输入格式
输入的第一行包含一个整数 \(n(1 \le n \le 100000)\) ,用于表示数组中元素的个数。
输入的第二行包含 \(n\) 个整数,两两之间有一个空格,用于表示数组中的元素 \(a_1, a_2, ..., a_n(1 \le a_i \le 10^9,并且 a_1 \le a_2 \le ... \le a_n)\) 。
输入的第三行包含一个整数 \(q(1 \le q \le 100000)\) ,用于表示询问的次数。
接下来 \(q\) 行,每行包含一个整数 \(x(1 \le x \le 10^9)\) ,表示要询问的数。
输出格式
对于每一次询问的 \(x\) ,如果数组 \(a\) 中存在大于等于 \(x\) 的元素,则输出数组 \(a\) 中满足大于等于 \(x\) 条件的所有元素中最小的元素;否则输出“-1” 。每个输出结果占单独的一行。
样例输入
5
1 3 5 7 9
3
2
9
11
样例输出
3
9
-1
题目分析
本题涉及算法:二分。
因为数组是按照单调非递增的顺序给我们的(即满足 \(a_i \le a_{i+1}\) ),所以我们按照如下方式进行二分:
首先我们开一个变量 \(L = 1\) 用于表示初始时自变量(数组坐标)的左边界;在一个变量 \(L = n\) 用于表示初始时自变量(数组坐标)的右边界。
我们还需要开一个变量 \(res\) 用于存储答案(即大于等于 \(x\) 的最大的数),初始时 \(res = -1\) (如果结束的时候 \(res\) 还是 \(-1\) 则说明没有符合要求的答案)。
然后只要满足 \(L \le R\) 条件,我们就循环执行如下操作:
开一个变量 \(mid\) 并令 \(mid = (L+R)/2\) ,然后判断:
- 如果 \(a[mid] \ge x\) ,说明这个 \(a[mid]\) 是满足 \(\ge x\) 的当前最优解;所以我们需要将 \(res\) 更新为 \(mid\) ,同时执行 \(R = mid-1\) 。因为当前最优解并不一定是最终最优解,\(a[mid] \ge x\) 能够说明的是 \([mid,R]\) 范围内的所有元素都 \(\ge x\) ,但是并不能说明 \([L, mid-1]\) 范围内是否还存在比 \(a[mid]\) 更小的元素同样 \(\ge x\) ,所以我们还是要继续循环的进左半边去查找(所以才需要执行 \(R = mid -1\) 操作)。
- 如果 \(a[mid] \lt x\) ,说明 \(a[L]\) 到 \(a[mid]\) 范围内的所有元素都 \(\lt x\) ,所以我们只需要执行 \(L = mid +1\) 进右半边继续查找。
这样,当循环结束的时候(不满足 \(L \le R\) 条件则循环就结束了):
- 如果 \(R = -1\) ,说明没有找到答案(因为只要找到答案 \(res\) 就会更新,如果到循环结束的时候 \(res\) 还是等于 \(-1\) 则说明一个满足要求的答案都没有找到过);
- 否则,\(res\) 对应的就是大于等于 \(x\) 的最小元素的坐标,我们直接输出 \(a[res]\) 即可。
这里需要注意的是:一旦找到了当前最优解,我就更新 \(res\) 为 \(mid\) (令 \(res\) 记录最优解的自变量);但是其实我们也可以更新 \(res\) 为 \(a[mid]\)(令 \(res\) 记录最优解的应变量)。之所以我更习惯用 \(res\) 记录自变量的原因是:可以直接通过自变量得到应变量,而不能直接通过应变量得到自变量,所以使用 \(res\) 记录自变量会好一些。
实现代码如下:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int n, a[maxn], q, x;
// solve函数用于返回大于等于x的最小元素
int solve(int x) {
int L = 1, R = n, res = -1;
while (L <= R) {
int mid = (L + R) / 2;
if (a[mid] >= x) {
res = mid;
R = mid - 1;
}
else L = mid + 1;
}
if (res == -1) return -1; // 如果循环结束res==-1,说明没有找到答案
return a[res]; // 因为res存的是最优解的坐标,所以返回a[res]
}
int main() {
cin >> n;
for (int i = 1; i <= n; i ++) cin >> a[i];
cin >> q;
while (q --) {
cin >> x;
cout << solve(x) << endl;
}
return 0;
}
二分练习题2 查找大于等于x的最小元素 题解的更多相关文章
- 二分练习题3 查找小于x的最大元素 题解
题目描述 现在告诉你一个长度为 \(n\) 的有序数组 \(a_1, a_2, ..., a_n\) ,以及 \(q\) 次询问,每次询问会给你一个数 \(x\) ,对于每次询问,你需要输出数组 \( ...
- P1042 查找大于等于x的最小元素
题目描述 现在告诉你一个长度为 \(n\) 的有序数组 \(a_1, a_2, ..., a_n\) ,以及 \(q\) 次询问,每次询问会给你一个数 \(x\) ,对于每次询问,你需要输出数组 \( ...
- 笔试算法题(05):转换BST为双向链表 & 查找栈中的最小元素
出题:把二元查找树转变成排序的双向链表.输入一棵二元查找树,要求将该二元查找树按照中序转换成一个排序的双向链表,要求不能创建任何新的节点,只能调整指针的指向: 分析: 递归的思路,当前节点需要进行的处 ...
- python 练习题:使用迭代查找一个list中最小和最大值,并返回一个tuple
# -*- coding: utf-8 -*- # 请使用迭代查找一个list中最小和最大值,并返回一个tuple from collections import Iterable def findM ...
- 【Python实践-5】使用迭代查找一个list中最小和最大值
# -*- coding: utf-8 -*- #使用迭代查找一个list中最小和最大值,并返回一个tuple #遍历list,找到最小值 def findMinAndMax(L): if L==[] ...
- 9.算法之顺序、二分、hash查找
一.查找/搜索 - 我们现在把注意力转向计算中经常出现的一些问题,即搜索或查找的问题.搜索是在元素集合中查找特定元素的算法过程.搜索通常对于元素是否存在返回 True 或 False.有时它可能返回元 ...
- 请使用迭代查找一个list中最小和最大值,并返回一个tuple
如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration). 在Python中,迭代是通过for ... in来完成的,而很多语 ...
- 计蒜客 41387.XKC's basketball team-线段树(区间查找大于等于x的最靠右的位置) (The Preliminary Contest for ICPC Asia Xuzhou 2019 E.) 2019年徐州网络赛
XKC's basketball team XKC , the captain of the basketball team , is directing a train of nn team mem ...
- 算法之顺序、二分、hash查找
算法之顺序.二分.hash查找 一.查找/搜索 - 我们现在把注意力转向计算中经常出现的一些问题,即搜索或查找的问题.搜索是在元素集合中查找特定元素的算法过程.搜索通常对于元素是否存在返回 Tru ...
随机推荐
- python --- 零碎
1.匿名输出: lambda x : print(x))(100) #冒号前输入量 ,冒号后是输出量结果:100 2.导入调用其他python文件: test1.py #第一个python文件 def ...
- 洛谷 P4401 [IOI2007]Miners 矿工配餐
题意简述 有两个矿洞,已知食物的种类(≤3)和顺序,将他们送往任一矿洞, 若一个矿洞3次食物相同,贡献1:若有2种不同食物,贡献2:若有3种不同食物,贡献3 求最大贡献 题解思路 food[i] 为当 ...
- (十三)c#Winform自定义控件-导航菜单
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- vim 基础配置
最近在使用 python 搞服务, 简单配置了一个 vim, 配置了自动补全以及背景色 .(ps:搜狗输入法快捷键占用真是太坑爹,改用谷歌输入法,世界安静了) 具体配置如下: 一. 安装插件 1.克隆 ...
- Alfred上可提高工作效率的Workflow推荐
温馨提示:本文中Alfred是Mac平台的工具,不适用于其他平台. Alfred是Mac平台上被很多人吹爆的一款效率提升软件,我刚毕业工作的时候就看到公司内网有人推荐,但没有尝试. 后来我跳槽后自己买 ...
- 浅谈Http与Https
大家都知道,在客户端与服务器数据传输的过程中,http协议的传输是不安全的,也就是一般情况下http是明文传输的.但https协议的数据传输是安全的,也就是说https数据的传输是经过加密. 在客户端 ...
- (三)(1)线程间通信---wait和notify的使用
这篇博客记录线程间通信相关api使用以及理解. 首先第一点,我之前的博客里的线程之间也是通信的,但是他们的通信是建立在访问的是同一个变量上的,相当于是变量.数据层面上的通信,而下面要讲的是线程层面上的 ...
- rocketMQ部署
rocketMQ部署(单机) 1. 环境: CentOS7 64 & JDK1.8+ 64 & 用户:www 2. 下载binary文件包: ...
- ECMAScript---布尔类型、null、undefined详解
布尔类型中 至只有 true和false 在开发中它是非常重要的两个值,尤其是在条件判断中 如何把其他类型转换为布尔类型? 1.Boolean() Boolean(1); //true Boolean ...
- Delphi - cxGrid设定字段类型为CheckBox
cxGrid设定字段类型为CheckBox 1:设定OraQuery属性 CachedUpdates设定为True: 双击打开OraQuery,选中Update SQLs页面,Insert.Updat ...