先给定一个数列,然后再给一个数,在数列中找到离给定数最近的数字并输出
所谓最近是指两个数做差的绝对值最小
输入格式:
第一行为一个整数n,代表数列中元素的个数,并保证有1≤n≤100000。
第二行给出数列里的n个整数,保证数列元素的大小均在0到1,000,000,000之间。
第三行包含一个整数m,为要询问的给定值的个数,并有1≤m≤10000
接下来m行,每行一个整数,为要询问最接近元素的给定值。所有给定值的大小均在 1 到 1,000,000,000 之间。
输出格式:
输出m行,每行一个整数,为最接近相应给定值的元素值,保持输入顺序。若有多个值满足条件,输出最小的一个。
输入样例:
在这里给出一组输入。例如:
3
2 5 8
2
10
5
输出样例:
在这里给出相应的输出。例如:
8
5
第一种是自己想的用二分法折半查找数字,若数组中存在查找的数字,直接输出;不存在则找到的数一定在离输入数字最近的位置,则只需要查找是否相邻的数字还有比它相减绝对值更小的
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int x[100010];
int n;
int mini(int s)
{
if(s>x[n-1])
{
return x[n-1];
}
if(s<x[0])
{
return x[0];
}
int l=0;
int r=n-1;
int mid=(l+r)/2;
while(l<r)
{
if(s<x[mid])
{
r=mid-1;
mid=(l+r)/2;
}
else if(s>x[mid])
{
l=mid+1;
mid=(l+r)/2;
}
else
{
return x[mid];
}
}
if(s<x[mid])
{
if(abs(x[mid]-s)<abs(x[mid-1]-s))
{
return x[mid];
}
return x[mid-1];
}
if(abs(x[mid]-s)>abs(x[mid+1]-s))
{
return x[mid+1];
}
return x[mid];
}
int main()
{
int m;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&x[i]);
}
sort(x,x+n);
scanf("%d",&m);
int q;
while(m--)
{
scanf("%d",&q);
printf("%d\n",mini(q));
}
return 0;
}
第二种方法相似,引用一种函数lower_bound(数组名,数组名+容量,查询数字)-数组名
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int x[100010];
int n;
int main()
{
int m;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&x[i]);
}
sort(x,x+n);
scanf("%d",&m);
int q;
while(m--)
{
scanf("%d",&q);
if(q<x[0])
{
printf("%d\n",x[0]);
continue;
}
int a=lower_bound(x,x+n,q)-x-1;
if(a==n-1)
{
printf("%d\n",x[n-1]);
}
else if(abs(x[a]-q)>abs(x[a+1]-q))
{
printf("%d\n",x[a+1]);
}
else
{
printf("%d\n",x[a]);
}
}
return 0;
}