UVA10487Closest Sums(二分)
来源:互联网 发布:lvs调度算法 编辑:程序博客网 时间:2024/05/16 10:49
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.
题目大意:
给你N个数,其中任意两个数相加的和sum 尽量靠近m[i],找到这个最接近sum。 n<=1e3,m<=25;
朴素想法:
算出所有n^2种可能,对于每一个询问遍历查找。时间复杂度n^2+ m*n*n*K(很多组数据)。
优化:
1.先排序,查找的时候用二分。n^2+n^2lgn^2+m*log2(n^2)*K;
2.还有一种更加优化的方法。不用算出n^2种结果。
先将n个数排序。对于每个询问 枚举一个数i,再用二分去查找另一个j。时间复杂度m*n*log2(n)*k;
实现:
窝用的是第三种优化方法。实现上需要注意的是,
其一,在二分查找j的时候,如何剔除已经枚举了的数i。有可能最后二分出来的结果是i+i。。然而这是不允许的,于是需要判断if(i==j)。
其二,有可能我们二分出来的结果并不是最接近的那个数。因为二分只能控制找出的那个数《=我们想要的那个数,,而可能比二分出来的结果大一点点的数加起来更加接近目标。于是窝们需要对左or右的数做一个判断取优。
// Created by ZYD in 2015.// Copyright (c) 2015 ZYD. All rights reserved.//#include <cstdio>#include <cstdlib>#include <iostream>#include <algorithm>#include <cstring>#include <climits>#include <string>#include <vector>#include <cmath>#include <stack>#include <queue>#include <set>#include <map>using namespace std;#define maxn 1000000#define ll long long#define mk make_pair#define pb push_back#define mem(array) memset(array,0,sizeof(array))typedef pair<int,int> P;int tot=0,n,a[2000],m,b,t,anss,ans,l,r,mid,x,bz;int main(){ freopen("in.txt","r",stdin); while(~scanf("%d",&n) && n) { mem(a); printf("Case %d:\n",++tot); for(int i=1;i<=n;i++) cin>>a[i]; sort(a+1,a+n+1); cin>>m; for(int i=1;i<=m;i++) { cin>>x;anss=maxn; for(int j=1;j<=n;j++) { l=1;r=n; bz=x-a[j]; while(l<r) { mid=(l+r) /2; if(a[mid]>=bz) r=mid; else l=mid+1; } r=l+1; if(l==j) l--; if(r==j) r++; if(l) ans=a[l]+a[j]; else ans=a[r]+a[j]; if(r<=n && fabs(a[r]+a[j]-x)<fabs(ans-x)) ans=a[r]+a[j]; if((l-1)!=j && (l-1)>0 && fabs(a[l-1]+a[j]-x)<fabs(ans-x)) ans=a[l-1]+a[j];//if(tot==4) cout<<ans<<endl; if(fabs(ans-x)<fabs(anss-x)) anss=ans; } printf("Closest sum to %d is %d.\n",x,anss); } } return 0;}
- UVA10487Closest Sums(二分)
- uva10487Closest Sums
- UVA 10487 Closest Sums (二分查找)
- uva 10487 Closest Sums(二分搜索)
- uva - 10487 - Closest Sums(二分查找)
- uva:10487 - Closest Sums(二分查找)
- UVA - 10487 Closest Sums(二分查找)
- UVA Closest Sums(二分查找)
- UVA 10487 Closest Sums(二分)
- UVA - 10487 - Closest Sums (二分求解)
- Closest Sums - UVa10487 二分
- [二分搜索]Closest Sums uva10487
- UVa 10487 Closest Sums (遍历&二分查找)
- (POJ2140)Herd Sums
- Sums
- sums
- uva 10487 Closest Sums (遍历&二分查找&&双向查找)
- codeforces 837F. Prefix Sums 思维+二分+组合数
- Java笔试、面试中常见的题目记录
- Python线程指南
- 单例模式
- ZOJ 1243
- 黑马程序员——————IO的几个练习与自己的几个思考
- UVA10487Closest Sums(二分)
- 求模和取余
- 杭电1163
- 给一个数轴,包括正无穷和负无穷,从原点0开始向目标位置x走动(x为整数),第i步,步长为i,求到x的最少步数
- JavaEE 13个技术规范总结
- 【NOJ】(Java)完美立方
- C#写的64位windows窗口应用程序打包安装后提示“未能加载文件或程序集‘System.Data.SQLite’”解决方法
- Install mayavi on windows 10 32 bit professional
- 【LeetCode】Serialize and Deserialize Binary Tree 解题报告