二分练习
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
Hint
Author
#include <bits/stdc++.h>
using namespace std;
int x[10000010];
int minimum(int x[],int s,int t,int key)//求下界值
{
int i=s,j=t;
int reset=-1;//设为-1
while(i<=j)//不断循环至i>j
{
int mid=(i+j)/2;
if(key>=x[mid])
{
i=mid+1;
reset=mid;
}
else
{
j=mid-1;
}
}
return reset;
}
int maximum(int x[],int s,int t,int key)//求上界值
{
int i=s,j=t;
int reset=-1;
while(i<=j)
{
int mid=(i+j)/2;
if(key>x[mid])
{
i=mid+1;
}
else
{
j=mid-1;
reset=mid;
}
}
return reset;
}
int main()
{
int n,m,i,key;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=0; i<n; i++)
{
scanf("%d",&x[i]);
}
sort(x,x+n);//调用排序函数
while(m--)
{
scanf("%d",&key);
int mi=minimum(x,0,n-1,key);
int ma=maximum(x,0,n-1,key);
if(mi==-1)//第一种情况
{
printf("%d\n",x[ma]);//注意输出的是数组值,不要输出ma或mi
}
else if(ma==-1)//第二种情况
{
printf("%d\n",x[mi]);
}
else if(x[ma]==x[mi])//第三种情况
printf("%d\n",x[mi]);
else//(数组中没有key的三种情况)
{
if(key-x[mi]==x[ma]-key)//第四种情况,上下界和key差值一样
{
printf("%d %d\n",x[mi],x[ma]);
}
else if(key-x[mi]>x[ma]-key)//第五种情况
{
printf("%d\n",x[ma]);
}
else//第六种情况
printf("%d\n",x[mi]);
}
}
printf("\n");
}
return 0;
}