UVA 10487 Closest Sums(二分)

UVA 10487 Closest Sums

Given is a set of integers and then a sequence of queries. A query gives you a number and asks to find a sum of two distinct numbers from the set, which is closest to the query number.

Input

Input contains multiple cases.

Each case starts with an integer n (1<n<=1000), which indicates, how many numbers are in the set of integer. Next n lines contain n numbers. Of course there is only one number in a single line. The next line contains a positive integer
m giving the number of queries, 0 < m < 25. The next m lines contain an integer of the query, one per line.

Input is terminated by a case whose n=0. Surely, this case needs no processing.

Output

Output should be organized as in the sample below. For each query output one line giving the query value and the closest sum in the format as in the sample. Inputs will be such that no ties will occur.

Sample input

5

3 
12 
17 
33 
34 
3 
1 
51 
30 
3 
1 
2 
3 
3 
1 
2 
3 

3

1 
2 
3 
3 
4 
5 
6 
0 

Sample output

Case 1:     
Closest sum to 1 is 15.     
Closest sum to 51 is 51.     
Closest sum to 30 is 29.     
Case 2:     
Closest sum to 1 is 3.     
Closest sum to 2 is 3.     
Closest sum to 3 is 3.     
Case 3:     
Closest sum to 4 is 4.     
Closest sum to 5 is 5.     
Closest sum to 6 is 5.

题目大意:给出由一些数字组成的集合,然后再输入一个字, 找出集合中不同的两个数的和最接近输入这个数的值

解题思路:现将每个数的两两之间的和存在一个数组里,然后二分,要注意题目里输出中间是没有空行的(被坑了好久)。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
long long num[1005], ans[1005], sum[1000005];
int main() {
	int Case = 1;
	int n, m;
	while (scanf("%d", &n), n) {
		for (int i = 0; i < n; i++) {
			scanf("%lld", &num[i]);
		}
		scanf("%d", &m);
		for (int i = 0; i < m; i++) {
			scanf("%lld", &ans[i]);
		}
		int cnt = 0;
		for (int i = 0; i < n; i++) {
			for (int j = i + 1; j < n; j++) {
				sum[cnt++] = num[i] + num[j];
			}
		}
		sort(sum, sum + cnt);
		printf("Case %d:\n", Case++);
		int Ans;
		for (int i = 0; i < m; i++) {
			int l = 0, r = cnt - 1;
			long long Ans = 0, mid = (l + r) / 2, min = 999999999;
			if (sum[mid] == ans[i]) {
				Ans = ans[i];
			}
			else if (sum[mid] < ans[i]) {
				while (mid <= r) {
					if (min > abs(ans[i] - sum[mid])) {
						min = abs(ans[i] - sum[mid]);
						Ans = sum[mid];
					}
					mid++;
				}
			}
			else {
				while (mid >= l) {
					if (min > abs(sum[mid] - ans[i])) {
						min = abs(sum[mid] - ans[i]);
						Ans = sum[mid];
					}
					mid--;
				}
			}
			printf("Closest sum to %lld is %lld.\n", ans[i], Ans);
		}
	}
	return 0;
}
时间: 2024-10-25 01:58:24

UVA 10487 Closest Sums(二分)的相关文章

UVA - 10487 - Closest Sums (二分求解)

传送:UVA - 10487 10487 Closest Sums Given is a set of integers and then a sequence of queries. A query gives you a number and asks to find a sum of two distinct numbers from the set, which is closest to the query number. Input Input contains multiple c

uva 10487 Closest Sums (遍历&amp;二分查找&amp;&amp;双向查找)

题目大意:先给定n个数字,现在要求算出这n个数字的两两之和保存到sum数组,然后在给定m个数,要求找到和每一个数最接近的sum[i]: 挨个计算每个属于其他数之间的sum,然后排序: 查找时有两种方法:二分查找&&双向查找:当然二分查找的效率比后者高了很多,但是都能AC. 提供一条新思路,并不一定非要用二分. 双向查找: #include<stdio.h> #include<algorithm> #include<stdlib.h> using name

uva:10487 - Closest Sums(二分查找)

题目:10487 - Closest Sums 题目大意:给出一组数据,再给出m个查询的数字.要求找到这组数据里的两个数据相加的和最靠近这个查询的数据,输出那两个数据的和. 解题思路:二分查找,这样找到的话,就输出查询的数值,但是要注意找不到的情况:这里最靠近的值不一定是在找不到的时刻的前一次数据,所以要维护最靠近的要查询数的数值. 代码: #include <stdio.h> #include <algorithm> #include <stdlib.h> using

UVA Closest Sums(二分查找)

Problem D Closest Sums Input: standard input Output: standard output Time Limit: 3 seconds Given is a set of integers and then a sequence of queries. A query gives you a number and asks to find a sum of two distinct numbers from the set, which is clo

UVA10487 Closest Sums【暴力+二分】

Given is a set of integers and then a sequence of queries. A query gives you a number and asks to find a sum of two distinct numbers from the set, which is closest to the query number. Input Input contains multiple cases. ????Each case starts with an

uva-10487 - Closest Sums

暴力枚举后去重最后二分加推断找答案 #include<iostream> #include<map> #include<string> #include<cstring> #include<cstdio> #include<cstdlib> #include<cmath> #include<queue> #include<vector> #include<algorithm> using

UVA.11997- K Smallest Sums, OJ4TH.368 - Magry&#39;s Sum I

感谢算法助教们给了这么一个好题... 题意: 给出n个数组,每个数组有n个元素,我们从每个数组中挑选一个元素,共计n个元素求和,得到共计 $ k^k $ 种sum,求sum中的最小n个值. 利用二分查找符合条件的最大sum值,dfs搜索判断二分条件.最坏时间复杂度 $O(n^{2}log(n*Max(a[i][j])) $ 刘汝佳训练指南上给出了优先队列多路归并的思想. 思路1代码: 1 #include<cstdio> 2 #include<iostream> 3 #includ

uva 1356 - Bridge(积分+二分)

题目链接:uva 1356 - Bridge 题目大意:在一座长度为B的桥上建若干个塔,塔的间距不能超过D,塔的高度为H,塔之间的绳索形成全等的抛物线.绳索的总长度为L.问在建最少塔的情况下,绳索的最下段离地面的高度. 解题思路:贪心的思想求出最少情况下建立的塔数. 二分高度,然后用积分求出两塔之间绳索的长度. C++ 积分 #include <cstdio> #include <cstring> #include <cmath> #include <algori

2019杭电多校第四场hdu6621 K-th Closest Distance(二分答案+主席树)

K-th Closest Distance 题目传送门 解题思路 二分答案+主席树 先建主席树,然后二分答案mid,在l和r的区间内查询[p-mid, p+mid]的范围内的数的个数,如果大于k则说明这个范围内存在第k小的数,r=mid,否则不存在,l=mid+1. 代码如下 #include <bits/stdc++.h> #define INF 0x3f3f3f3f using namespace std; typedef long long ll; inline int read(){