Description
在含有n(1<=n<=9000000)个元素的非降序列中,要求在log(n)时间内查找与给定值最接近的元素。
Input
第一行为整数n和m,n为非降序列长度(1 <= n <= 1000000),m为询问次数(1 <= m <= 10000)。第二行包含n个整数,为非降序列各元素。所有元素的大小均在0-1,000,000,000之间。接下来m行,每行一个整数,为要询问最接近元素的给定值。所有给定值的大小均在0-1,000,000,000之间。
Output
m行,每行一个整数,为最接近相应给定值的元素值,保持输入顺序。若有多个值满足条件,输出最小的一个。
Sample Input
5 3
1 4 8 9 10
1
2
6
Sample Output
1
1
4
这道题要求logn的时间复杂度,所以只能用二分搜索来完成。思路很简单,直接上代码就能看懂,不废话。
#include<iostream>
#include<stdio.h>
using namespace std;
int a[1000000];
int bs(int a[], int n, int target, int &i, int &j){
int left=0;
int right=n-1;
int mid;
while(left<=right){
mid=(left+right)/2;
if(target==a[mid]){
i=mid;
j=mid;
// cout<<i<<" "<<j;
printf("%d\n", a[mid]);
return mid;
}
else if(target>a[mid]){
left=mid+1;
}
else{
right=mid-1;
}
}
i=right;
j=left;
//cout<<i<<" "<<j;
if(i<0){
printf("%d\n", a[0]);
}
else if(j>=n){
printf("%d\n", a[n-1]);
}
else{
int l=(target-a[i])>0?(target-a[i]):(-(target-a[i]));
int r=(target-a[j])>0?(target-a[j]):(-(target-a[j]));
if(l<r){
printf("%d\n", a[i]);
}
else if(l==r){
printf("%d\n", a[i]);
}
else{
printf("%d\n", a[i]);
}
}
return -1;
}
int main(){
int n;
int m;
int i, j;
int b[10000];
cin>>n>>m;
for(int p=0; p<n; p++){
cin>>a[p];
}
for(int p=0; p<m; p++){
cin>>b[p];
}
// cout<<b[2]<<endl<<endl;
// bs(a, n, b[2], i, j);
for(int p=0; p<m; p++){
bs(a, n, b[p], i, j);
}
}