题目描述

现在告诉你一个长度为 \(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. 笑谈CSS的伪元素

    今晚上我们来简单的聊一聊CSS的伪元素,多说无益,开聊 GG: 话说盘古开天辟地之时. QQ:嗨,咱今天还能讲的完吗?您给来点实际的啊. GG:要听实际的是吧,得嘞,那今天咱就来聊一聊CSS里的伪元素 ...

  2. 本地(任意)时间戳转化(转换)标准时间格式 js(eg:2019-05-07 17:49:12)

    <script> function getLocalTime(timestamp) { // 如果以秒为单位 // var dateObj = new Date(timestamp * 1 ...

  3. Linux 精确判断是否同一文件--及终端获取字符串md5 的值

    背景 今天发现一个同事用 文件大小 对比,来判断编译所得的一个可执行文件是不是同一个文件. 讲道理 这种方式出错的概率很低,但是用这样的方法,一旦出错就容易被坑一把狠的. 所以我来分享一下 md5 在 ...

  4. Lasso估计学习笔记(二)

    先看Lasso估计学习笔记(一),这篇是续的上一篇

  5. wordpress修改登录密码

    wordpress忘记密码更改 网上搜到的方法: 1.后台邮件重置: 2,phpmyadmin登录数据库,执行mysql语句或者在wp_users表中重置密码: 3,利用php文件重置. 这是提供一种 ...

  6. Zabbix-Web监控介绍篇

    一.Web监控需求 监控一台Zabbix 3.0的WEB服务是否正常,包括登陆页,登陆后页面,退出页面 ps:zabbix的WEB监控可以实现登录后监控 二.监控环境介绍 监控服务器版本:zabbix ...

  7. JMeter使用JSON Extractor插件实现将一个接口的JSON返回值作为下一个接口的入参

    ##补充## 接口响应数据,一般为JSON,HTML格式的数据. 对于HTML的响应结果提取,可以使用正则表达式,也可以通过XPath来提取:对于JSON格式的数据,可以用正则表达式,JSON Ext ...

  8. Git安装与使用(windows环境)(一)----Git安装、生成公钥和私钥、添加SSH

    安装 1.从官网下载git:http://git-scm.com/downloads 2.安装git,选择git组件安装,如下图 3.一直next,直到出现下面的窗口.这里是选择命令行形式.(可以理解 ...

  9. 启xin宝app的token算法破解——token分析篇(三)

    前两篇文章分析该APP的抓包.的逆向: 启xin宝app的token算法破解--抓包分析篇(一) 启xin宝app的token算法破解--逆向篇(二) 本篇就将对token静态分析,其实很简单就可以搞 ...

  10. stringbuffer与stringbuilder区别分析

    它们到底都有什么区别呢! 三者都是用来对字符串进行操作,String通常用来定义一个变量,而StringBuilder StringBuffer则通常用来对字符串进行拼接等操作.但其实String同样 ...