题目描述
给你一个序列,然后给你m个元素,让你从序列中找出与每个元素最接近的数字输出来,如果有两个就输出两个。
输入
多组输入,第一行给你两个数n(0 < n < 10000000),m(0 < m < n),接下来是数列的n个数,然后再输入m个元素,让你找出最接近每个元素的值。如果有两个,按从小到大输出。
输出
这m个数分别输出最接近每个元素的值,组与组之间输出一个空行。
示例输入
8 4 1 2 3 4 5 6 8 11 4 9 2 7
示例输出
4 8 2 6 8
提示:典型的二分法,不过不是查找确切的数,而是相近的,由题意可知结果要么是两个数要么是一个数,先调用一个sort函数,将给的数组从小到大排序(这里是为了有两个结果的情况的时候好吧他们找出);
参考代码:
#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
int a[10000007];
int main()
{
int n,left,right,i,j,mid,m,k,t;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=0;i<n;i++)
scanf("%d",&a[i]);
sort(a,a+n);//注意要放在循环外边,不然会超时,开始我就是这样错的,还是让学长改的。
for(j=0;j<m;j++)
{
scanf("%d",&k);
left=0,right=n-1,t=0;
if(k>a[n-1])//判断当测试数据大于最大值的情况,开始因为这个错了好几次
printf("%d\n",a[n-1]);
else if(k<a[0])//判断测试数据小于最小值的情况
printf("%d\n",a[0]);
else
{
while(left<=right)
{
mid=(left+right)/2;
if(k==a[mid])
t=1;
if(k<a[mid])
right=mid-1;
else
left=mid+1;
}//如果测试数据不在数组里,那么最后的区间也是自接近测试数据的
if(t)//数据里有等于测试数据的直接输出
printf("%d\n",k);
else
{
if(a[left]-k==k-a[right])
printf("%d %d\n",a[right],a[left]);//最后区间两边和测试数据一样接近,都打印出来
else if(a[left]-k<k-a[right])//否则打印更接近的
printf("%d\n",a[left]);
else
printf("%d\n",a[right]);
}
}
}
printf("\n");
}
return 0;
}