题目描述

现在告诉你一个长度为 \(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的最小元素 题解的更多相关文章

  1. 二分练习题3 查找小于x的最大元素 题解

    题目描述 现在告诉你一个长度为 \(n\) 的有序数组 \(a_1, a_2, ..., a_n\) ,以及 \(q\) 次询问,每次询问会给你一个数 \(x\) ,对于每次询问,你需要输出数组 \( ...

  2. P1042 查找大于等于x的最小元素

    题目描述 现在告诉你一个长度为 \(n\) 的有序数组 \(a_1, a_2, ..., a_n\) ,以及 \(q\) 次询问,每次询问会给你一个数 \(x\) ,对于每次询问,你需要输出数组 \( ...

  3. 笔试算法题(05):转换BST为双向链表 & 查找栈中的最小元素

    出题:把二元查找树转变成排序的双向链表.输入一棵二元查找树,要求将该二元查找树按照中序转换成一个排序的双向链表,要求不能创建任何新的节点,只能调整指针的指向: 分析: 递归的思路,当前节点需要进行的处 ...

  4. python 练习题:使用迭代查找一个list中最小和最大值,并返回一个tuple

    # -*- coding: utf-8 -*- # 请使用迭代查找一个list中最小和最大值,并返回一个tuple from collections import Iterable def findM ...

  5. 【Python实践-5】使用迭代查找一个list中最小和最大值

    # -*- coding: utf-8 -*- #使用迭代查找一个list中最小和最大值,并返回一个tuple #遍历list,找到最小值 def findMinAndMax(L): if L==[] ...

  6. 9.算法之顺序、二分、hash查找

    一.查找/搜索 - 我们现在把注意力转向计算中经常出现的一些问题,即搜索或查找的问题.搜索是在元素集合中查找特定元素的算法过程.搜索通常对于元素是否存在返回 True 或 False.有时它可能返回元 ...

  7. 请使用迭代查找一个list中最小和最大值,并返回一个tuple

    如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration). 在Python中,迭代是通过for ... in来完成的,而很多语 ...

  8. 计蒜客 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 ...

  9. 算法之顺序、二分、hash查找

    算法之顺序.二分.hash查找   一.查找/搜索 - 我们现在把注意力转向计算中经常出现的一些问题,即搜索或查找的问题.搜索是在元素集合中查找特定元素的算法过程.搜索通常对于元素是否存在返回 Tru ...

随机推荐

  1. python --- 零碎

    1.匿名输出: lambda x : print(x))(100) #冒号前输入量 ,冒号后是输出量结果:100 2.导入调用其他python文件: test1.py #第一个python文件 def ...

  2. 洛谷 P4401 [IOI2007]Miners 矿工配餐

    题意简述 有两个矿洞,已知食物的种类(≤3)和顺序,将他们送往任一矿洞, 若一个矿洞3次食物相同,贡献1:若有2种不同食物,贡献2:若有3种不同食物,贡献3 求最大贡献 题解思路 food[i] 为当 ...

  3. (十三)c#Winform自定义控件-导航菜单

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  4. vim 基础配置

    最近在使用 python 搞服务, 简单配置了一个 vim, 配置了自动补全以及背景色 .(ps:搜狗输入法快捷键占用真是太坑爹,改用谷歌输入法,世界安静了) 具体配置如下: 一. 安装插件 1.克隆 ...

  5. Alfred上可提高工作效率的Workflow推荐

    温馨提示:本文中Alfred是Mac平台的工具,不适用于其他平台. Alfred是Mac平台上被很多人吹爆的一款效率提升软件,我刚毕业工作的时候就看到公司内网有人推荐,但没有尝试. 后来我跳槽后自己买 ...

  6. 浅谈Http与Https

    大家都知道,在客户端与服务器数据传输的过程中,http协议的传输是不安全的,也就是一般情况下http是明文传输的.但https协议的数据传输是安全的,也就是说https数据的传输是经过加密. 在客户端 ...

  7. (三)(1)线程间通信---wait和notify的使用

    这篇博客记录线程间通信相关api使用以及理解. 首先第一点,我之前的博客里的线程之间也是通信的,但是他们的通信是建立在访问的是同一个变量上的,相当于是变量.数据层面上的通信,而下面要讲的是线程层面上的 ...

  8. rocketMQ部署

    rocketMQ部署(单机) 1.          环境: CentOS7 64  &  JDK1.8+ 64  & 用户:www 2.          下载binary文件包: ...

  9. ECMAScript---布尔类型、null、undefined详解

    布尔类型中 至只有 true和false 在开发中它是非常重要的两个值,尤其是在条件判断中 如何把其他类型转换为布尔类型? 1.Boolean() Boolean(1); //true Boolean ...

  10. Delphi - cxGrid设定字段类型为CheckBox

    cxGrid设定字段类型为CheckBox 1:设定OraQuery属性 CachedUpdates设定为True: 双击打开OraQuery,选中Update SQLs页面,Insert.Updat ...