[Aizu] ITP2_6_C: Lower Bound

Problem

Portal

Solution

Analysis

要求在一个有序的序列中, 找出不小于k的下标位置, 也就是大于等于k的第一个数的位置
可以采用二分查找的思想, 不过循环结束的条件不再是找到跳出, 而是查找到某一个位置, 它本身大于等于k, 而它的紧邻前一位小于k, 或者它本身小于k, 而它的紧邻后一位大于等于k, 之后根据当前值决定返回它的下标, 还是它的后一位的下标

Design

使用数组存储数据, 类型为int
然后二分查找的时候, 终止条件为左右指针指向同一位置
中间的循环部分, 如果mid小于k, 在后半部分查找, 如果mid大于等于k, 在左半部分查找
结束循环后需要额外判断是不是不存在, 也就是返回n的条件
思路描述的不是很清晰, 具体看代码

code

#include <cstdio>
using namespace std;
 
int lower_bound(int* A, int n, int k) {
    int left = 0, right = n;
    int mid = (left + right) / 2;
    while (left < right) {
        if (A[mid] >= k) {
            right = mid;
        } else {
            left = mid + 1;
        }
        mid = (left + right) / 2;
    }
    if (mid == n)
        return n;
    return (A[mid] >= k ? mid : mid + 1);
}
 
int main(void) {
    int n, q, k;
    scanf("%d", &n);
    int* A = new int[n];
    for (int i = 0; i < n; i++) {
        scanf("%d", &A[i]);
    }
    scanf("%d", &q);
    while (q--) {
        scanf("%d", &k);
        printf("%d
", lower_bound(A, n, k));
    }
}

如果使用STL的话, 可以这样写

printf("%d
", distance(A.begin(), lower_bound(A.begin(), A.end(), tmp)));
原文地址:https://www.cnblogs.com/by-sknight/p/10880777.html