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 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.

问题链接UVA10487 Closest Sums
问题简述:(略)
问题分析
????给定n个数字,求这n个数字的两两之和中最接近于给定数的和。
????这是一个序列处理问题,可以暴力解决,也可以二分查找。
程序说明:(略)
参考链接:(略)
题记:(略)

AC的C++语言程序(二分)如下:

/* UVA10487 Closest Sums */

#include <bits/stdc++.h>

using namespace std;

const int N = 1000;
int a[N], sum[N * N / 2];

int Binary_Search(int b, int k)
{
    int left = 0, right = k - 1, mid, ans;
    for(;;) {
        if(right - left == 1) {
            ans = (sum[right] - b) < (b - sum[left]) ? sum[right] : sum[left];
            break;
        }
        mid = (left + right) / 2;
        if(sum[mid] > b)  right = mid;
        if(sum[mid] < b)  left = mid;
        if(sum[mid] == b) {ans = b ; break;}
    }
    return ans;
}

int main()
{
    int n, caseno = 0, m, b, k;
    while(~scanf("%d", &n) && n) {
        for(int i = 0; i < n; i++)
            scanf("%d", &a[i]);

        k = 0;
        for(int i = 0; i < n; i++)
            for(int j = i + 1; j < n; j++)
                sum[k++] = a[i] + a[j];
        sort(sum, sum + k);

        printf("Case %d:\n", ++caseno);

        scanf("%d", &m);
        for(int i = 1; i <= m; i++) {
            scanf("%d", &b);
            printf("Closest sum to %d is %d.\n", b, Binary_Search(b, k));
        }
    }

    return 0;
}

AC的C++语言程序(暴力)如下:

/* UVA10487 Closest Sums */

#include <bits/stdc++.h>

using namespace std;

const int N = 1000;
int a[N];

int main()
{
    int n, caseno = 0, m, b;
    while(~scanf("%d", &n) && n) {
        for(int i = 0; i < n; i++)
            scanf("%d", &a[i]);

        printf("Case %d:\n", ++caseno);

        scanf("%d", &m);
        for(int i = 1; i <= m; i++) {
            scanf("%d", &b);

            int minv = INT_MAX, t1, t2;
            for(int j = 0; j < n; j++)
                for(int k = j + 1; k < n; k++) {
                    int tmp = abs(a[j] + a[k] - b);
                    if( tmp < minv) {
                        minv = tmp;
                        t1 = a[j];
                        t2 = a[k];
                    }
                }

            printf("Closest sum to %d is %d.\n", b, t1+t2);
        }
    }

    return 0;
}

原文地址:https://www.cnblogs.com/tigerisland45/p/10372039.html

时间: 2024-07-28 17:41:23

UVA10487 Closest Sums【暴力+二分】的相关文章

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

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

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 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

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 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

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

poj3977 - subset - the second time - 暴力 + 二分

2017-08-26 11:38:42 writer:pprp 已经是第二次写这个题了,但是还是出了很多毛病 先给出AC代码: 解题思路: 之前在培训的时候只是笼统的讲了讲怎么做,进行二分对其中一边进行暴力枚举,对另一边用lower_bound查找算出的相反数 现在给出详细一点的思路: 答案可能在左边枚举的部分,也可能在右边枚举的部分,也可能在两边加起来的和中 所以从这三个方面不能少考虑: 还有用到了map所以算出来的key是唯一的,所以当算出来两个key相等的时候,应该采用value也就是cn

[51nod] 1267 4个数和为0 暴力+二分

给出N个整数,你来判断一下是否能够选出4个数,他们的和为0,可以则输出"Yes",否则输出"No". Input 第1行,1个数N,N为数组的长度(4 <= N <= 1000) 第2 - N + 1行:A[i](-10^9 <= A[i] <= 10^9) Output 如果可以选出4个数,使得他们的和为0,则输出"Yes",否则输出"No". Input示例 5 -1 1 -5 2 4 Output

Vijos P1116 一元三次方程求解【多解,暴力,二分】

一元三次方程求解 描述 有形如:ax^3+bx^2+cx+d=0 这样的一个一元三次方程.给出该方程中各项的系数(a,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与根之差的绝对值>=1.要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后2位. 格式 输入格式 输入该方程中各项的系数(a,b,c,d 均为实数), 输出格式 由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后2位. 样例1 样例输入1