题目描述

现在告诉你一个长度为 \(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. (二十八)c#Winform自定义控件-文本框(一)

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

  2. 世纪龙校招java开发一、二面 面经

    头一天做的笔试,涉及到计组基本知识,还有几道智力题.java部分很简单(真的很简单有点基础就划过了) 第二天收简历 在隔壁教室等 叫到你 你就去面试 一面:先自我介绍 1 == 和 equals区别( ...

  3. 基于STM32F429和Cube的ov2640程序

    1.ov2640和DCMI介绍 OV2640 是 OV(OmniVision)公司生产的一颗 1/4 寸的 CMOS UXGA(1632*1232)图 像传感器.该传感器体积小.工作电压低,提供单片 ...

  4. vue项目中引入Sass

    Sass作为目前成熟,稳定,强大的css扩展语言,让越来越多的前端工程师喜欢上它.下面介绍了如何在vue项目 中引入Sass. 首先在项目文件夹执行命令 npm install vue-cli -g, ...

  5. java 获取真实ip和根据ip获取ip所在地区

    import com.alibaba.fastjson.JSON; import javax.servlet.http.HttpServletRequest; import java.io.ByteA ...

  6. python 实现多个线程间消息队列传递,一个简单的列子

    #-*-coding:utf8-*-"""Producer and consumer models: 1. There are many producers and co ...

  7. Linux下各目录及其作用

    目录及其作用 /:根目录,一般根目录下只存放目录,不要存放件,/etc./bin./dev./lib./sbin应该和根目录放置在一个分区中 /bin: /usr/bin: 可执行二进制文件的目录,如 ...

  8. JSP指令、标签以及中文乱码

    JSP指令.标签以及中文乱码 一.JSP指令简介 JSP指令(directive)是为JSP引擎而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分. JSP指令的基本 ...

  9. python request接口测试笔记(1)

    python request接口测试笔记(1) 涉及到的功能说明: 需要登录拿到token,才能进行下一个接口的请求 读取csv文件中的信息,作为接口的参数 将接口响应结果,写入csv文件,以便分析统 ...

  10. 重识 ArrayList

    前言 ArrayList 作为 Java 集合框架中最常用的类,在一般情况下,用它存储集合数据最适合不过.知其然知其所以然,为了能更好地认识和使用 ArrayList,本文将从下面几方面深入理解 Ar ...