二分练习
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;
}