CF 600B Queries about less or equal elements --- 二分查找

 

  CF 600B

  题目大意:给定n,m,数组a(n个数),数组b(m个数),对每一个数组b中的元素,求数组a中小于等于数组该元素的个数。

  解题思路:对数组a进行排序,然后对每一个元素b[i],在数组a中进行二分查找第一个大于b[i]的位置即为结果

/* CF 600B Queries about less or equal elements --- 二分查找 */
#include <cstdio>
#include <algorithm>
using namespace std;

const int maxn = 200005;
int a[maxn], b[maxn];

/*
    @function:在数组A的区间[x,y)中查找第一个大于key的位置(二分查找求上界)
    @param1:A 待查找的数组名
    @param2: [x,y)表示左闭右开区间
    @param3: 查找的值
    @return: 返回第一个大于key的位置
*/
int BinarySearch(int *A, int x, int y, int key){
    while (x < y){
        int mid = x + (y - x) / 2;
        if (A[mid] <= key){
            x = mid + 1;
        }
        else{
            y = mid;
        }
    }//while(x<y)
    return x;
}

int main()
{
    int n, m;
    //n为数组a长度,m为数组b元素个数
    while (scanf("%d%d", &n, &m) == 2){
        for (int i = 0; i < n; ++i){
            scanf("%d", a + i);
        }//for(i)
        for (int i = 0; i < m; ++i){
            scanf("%d", b + i);
        }//for(i)
        sort(a, a + n);
        a[n] = 1 << 30;

        //对b中的每一个数b[i],在A中查找小于等于b[i]的数的个数
        for (int i = 0; i < m; ++i){
            int k = BinarySearch(a, 0, n, b[i]);
            printf(i == m - 1 ? "%d\n" : "%d ", k);
        }//for(i)
    }

    return 0;
}
View Code

 

  还可以直接利用STL中的upper_bound大大简化代码:

/* CF 600B Queries about less or equal elements --- 二分查找 */
#include <cstdio>
#include <algorithm>
using namespace std;

const int maxn = 200005;
int a[maxn];
int b[maxn];

int main()
{
    int n, m;
    while (scanf("%d%d", &n, &m) == 2){
        for (int i = 0; i < n; ++i){
            scanf("%d", a + i);
        }//for(i)
        sort(a, a + n);
        for (int i = 0; i < m; ++i){
            scanf("%d", b + i);
            int k = (upper_bound(a, a + n, b[i]) - a);
            printf(i == m - 1 ? "%d\n" : "%d ", k);
        }//for(i)
    }

    return 0;
}
View Code

 

posted @ 2016-04-10 16:33  tan90丶  阅读(231)  评论(0编辑  收藏  举报