题目一如既往的坑 1.未说明是否排序(必须排)2.两数字相同输出几个(输出一个 只能试)
与网上其他代码思路不太相同
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
#include<stdio.h>
int n;
int s[10000005];
void qsort(int l, int r)
{
if(l >= r)
return ;
int i = l, j = r;
int key = s[l];
while(i < j)
{
while(i < j && s[j] >= key) j--;
s[i] = s[j];
while(i < j && s[i] <= key) i++;
s[j] = s[i];
}
s[i] = key;
qsort(l, i - 1);
qsort(i + 1, r);
}
void ef(int l, int r, int key)
{
if(l > r) //当无相同数据时分三种情况
{
if(l == 0) //比最小值还小 输出最小值
printf("%d\n", s[l]);
else if(r == n - 1) // 比最大值还大 输出最大值
printf("%d\n", s[r]);
else //否则与他最接近的两个数必然为s[r]与s[l] 很简单 自行推导
{
if(key - s[r] > s[l] - key)
printf("%d\n", s[l]);
else if(key - s[r] < s[l] - key)
printf("%d\n", s[r]);
else
printf("%d %d\n", s[r], s[l]);
}
}
else
{
int mid = (l + r)/2;
if(s[mid] > key)
{
ef(l, mid - 1, key);
}
else if(s[mid] < key)
{
ef(mid + 1, r, key);
}
else
printf("%d\n", key); //题目中未说明两个数相同只输出一个 这个只能试了 还好我运气好
}
}
int main()
{
int m;
while(~scanf("%d %d", &n, &m))
{
int i;
for(i = 0; i < n; i++)
scanf("%d", &s[i]);
qsort(0, n - 1); //必须先排序
int key;
while(m--)
{
scanf("%d", &key);
ef(0, n - 1, key);
}
printf("\n");
}
return 0;
}