邓俊辉算法训练营习题 楼尔邦德(二分)

楼尔邦德
时间限制:2 sec

空间限制:256 MB

问题描述
给定包含 n 个数的序列 A。

再给出 Q 个询问,每个询问包含一个数 x,询问的是序列 A 中不小于 x 的最小整数是多少(无解输出-1)。

输入格式
第一行一个数 n,表示序列长度。

第二行 n 个用空格隔开的正整数,描述序列中的每一个元素。保证这些元素都不会超过 10^9。

第三行一个正整数 Q,表示询问个数。

接下来 Q 行,每行一个正整数 x,描述一个询问。

输出格式
输出 Q 行依次回答 Q 个询问,每行一个正整数,表示对应询问的答案。

样例输入
3
3 2 5
6
1
2
3
4
5
6
样例输出
2
2
3
5
5
-1

#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

vector<int> getAnswer(int n,int m,vector<int> q,vector<int> qn){
    vector<int> ans;
    ans.clear();//对ans进行清空
    //二分查找是建立在有序情况下的
    sort(q.begin(),q.end());

    for(int i = 0;i < m;i++){
        int key = qn[i];//用key代表询问值

        int L = -1,R = n,mid;
        //当L + 1 = R时,则R 存在不小于整数(可验证)
        while(L + 1 < R){
            mid = (L + R) >> 1;//向左移位 <==> 取中间值
            if(q[mid] < key)
                L = mid;//当q[mid] < key时 舍去左半边
            else
                R = mid;//当q[mid] >= key时 舍去右半边
        }
        if(R >= n)//此时说明所有的元素都比查询的值小 返回-1
            ans.push_back(-1);
        else
            ans.push_back(q[R]);
    }
    return ans;
}
int main(int argc, char const *argv[]) {
    //n代表元素的个数
    //q是元素集合
    int n;
    scanf("%d",&n);
    vector<int> q;
    for(int i = 0;i < n;i++){
        int ai;
        scanf("%d",&ai);
        q.push_back(ai);
    }

    //m代表询问个数
    //qn代表询问的值
    int m;
    scanf("%d",&m);
    vector<int> qn;
    for(int i = 0;i < m;i++){
        int bi;
        scanf("%d",&bi);
        qn.push_back(bi);
    }

    //返回询问结果
    vector<int> fin = getAnswer(n,m,q,qn);
    for(int i = 0;i < m;i++){
        printf("%d\n",fin[i]);

    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/WX_1218639030/article/details/83310200
今日推荐