不错的二分入门题,WA了一次,无意间写成了求比询问数小的最大数的位置了,完事后发现存在死循环,判了一下low==mid WA了,哈哈,这个错误得亏不是在比赛中翻得。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
int sum[500000];
int num[1010];
int bs(int low,int high,int key)
{
int mid;
while(low<high){
mid=(low+high)>>1;
if(sum[mid]==key) return mid;
// 下边这两行比较关键,我们只能选择找到比KEY大的最小数的位置
// 若改为选择比KEY小的最大数位置,则会成死循环
if(sum[mid]>key) high=mid;
else low=mid+1;
}
return low;
}
int main()
{
int n,ca=1;
while(cin>>n&&n){
int size=0;
for(int i=1;i<=n;i++) cin>>num[i];
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)
sum[size++]=num[i]+num[j];
sort(sum,sum+size);
int m;
cin>>m;
printf("Case %d:\n",ca++);
while(m--){
int q,ans;
cin>>q;
ans=bs(0,size-1,q);
if(!ans)
printf("Closest sum to %d is %d.\n",q,sum[ans]);
else
printf("Closest sum to %d is %d.\n",q,abs(sum[ans]-q)>abs(sum[ans-1]-q)?sum[ans-1]:sum[ans]);
}
}
return 0;
}