UVA 10487

  不错的二分入门题,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;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值