二分练习

来源:互联网 发布:飞思卡尔单片机课程 编辑:程序博客网 时间:2024/06/06 03:43

二分练习

Time Limit: 1000MS Memory Limit: 65536KB

Problem Description
给你一个序列,然后给你m个元素,让你从序列中找出与每个元素最接近的数字输出来,如果有两个就输出两个。

Input
多组输入,第一行给你两个数n(0 < n < 10000000),m(0 < m < n),接下来是数列的n个数,然后再输入m个元素,让你找出最接近每个元素的值。如果有两个,按从小到大输出。

Output
这m个数分别输出最接近每个元素的值,组与组之间输出一个空行。

Example Input
8 4
1 2 3 4 5 6 8 11
4
9
2
7

Example Output
4
8
2
6 8

#include <bits/stdc++.h>using namespace std;int n, rst = 0, key;int a[10000000];int find_left(int a[], int l, int r)  //查找元素上界{    if(l <= r)    {        int mid = (l + r) / 2;        if(a[mid] <= key)        {            rst = mid;            return find_left(a,mid+1,r);        }        else        {            return find_left(a,l,mid-1);        }    }    return rst;}int find_right(int a[], int l, int r)   //查找元素下界{    if(l <= r)    {        int mid = (l + r) / 2;        if(a[mid] >= key)        {            rst = mid;            return find_right(a,l,mid-1);        }        else        {            return find_right(a,mid+1,r);        }    }    return rst;}int main(){    int m;    while(~scanf("%d %d", &n, &m))    {        for(int i = 0; i < n; i++)            scanf("%d", &a[i]);        sort(a,a+n);        while(m--)        {            scanf("%d", &key);            int left = find_left(a,0,n-1);            int right = find_right(a,0,n-1);            if(abs(key-a[left]) != abs(key - a[right]))            {                if(abs(key-a[left]) < abs(key - a[right]))                    printf("%d\n", a[left]);                else                    printf("%d\n", a[right]);            }            else if(a[left] == a[right])                printf("%d\n", a[left]);            else                printf("%d %d\n", a[left], a[right]);        }        printf("\n");    }    return 0;}
原创粉丝点击