#P0154. lower_bound(a.begin(), a.end(), t)

lower_bound(a.begin(), a.end(), t)

题目描述

lower_bound(a.begin(),a.end(),t)lower\_bound(a.begin(), a.end(), t):返回容器 aa (升序) 中第一个大于等于 tt 的迭代器 (你可以理解成指针)。如果 tt 在数组范围内,显然返回的位置减一,即 pos1pos - 1 为最后一个小于 tt 的位置,但是要小心边界

初学者把迭代器当成指针就行, 慎用解引用操作,即 upper_bound(a.begin(),a.end(),t)*upper\_bound(a.begin(), a.end(), t),避免下标越界,最好加个判断。

注意: 本质上是二分法实现(数组需要具有单调性),所以需要排序后使用。

注意: 包含 #include <algorithm>

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
    int n, m;
    cin >> n >> m;
    vector<int> a(n);
    for(int i = 0; i < n; ++ i) cin >> a[i];
    sort(a.begin(), a.end());
    while(m --)
    {
        int t;
        cin >> t;
        vector<int>::iterator it = lower_bound(a.begin(), a.end(), t);
		if(it != a.end()) cout << it - a.begin() + 1 << endl;
		else cout << -1 << endl;
    }
    return 0;
}

考虑到 javajava 同学没有这个函数,我们直接手撕二分,具体到算法阶段再细讲

请不要改动我的代码l=0,r=n1l = 0, r = n - 1)是可以的。

#include<iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int a[N];
int n, q;
int main()
{
    cin >> n >> q;
    for(int i = 1;i <= n; ++ i) scanf("%d", &a[i]);
    sort(a + 1, a + 1 + n);
    while(q --)
    {
        int k;
        cin >> k;
        int l = 1, r = n;
        while(l < r)
        {
            int mid = l + r >> 1;
            if(a[mid] >= k) r = mid;//找到第一个 >= k 的数的位置
            else l = mid + 1;
        }
        if(l == n && a[l] >= k || l < n) cout << l << '\n';
        else cout << -1 << '\n';

    }
    return 0;
}

输入格式

11 行,为两个整数 n,mn, m

22 行,共 nn 个整数 a[i]a[i]

接下来 mm 行每行一个整数 tt

输出格式

mm 行,输出 aa 中第一个大于等于 tt 的元素位置 (下标从 11 开始)若不存在则输出 1-1

数据范围

1n105.1 ≤ n ≤ 10^5.

1m104.1 ≤ m ≤ 10^4.

1ai105.1 ≤ a_i ≤ 10^5.

输入样例:

3 2
3 2 1
1
4

输出样例:

1
-1