UVA1152- 枚举 /二分查找

Posted yy666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA1152- 枚举 /二分查找相关的知识,希望对你有一定的参考价值。

The SUM problem can be formulated as follows: given four lists A,B,C,D of integer values, compute how many quadruplet (a,b,c,d) ∈ A×B×C×D are such that a+b+c+d = 0. In the following, we assume that all lists have the same size n.


Input
The input begins with a single positive integer on a line by itself indicating the number of the cases following, each of them as described below. This line is followed by a blank line, and there is also a blank line between two consecutive inputs.
The ?rst line of the input ?le contains the size of the lists n (this value can be as large as 4000). We then have n lines containing four integer values (with absolute value as large as 228) that belong respectively to A,B,C and D.


Output
For each test case, your program has to write the number quadruplets whose sum is zero. The outputs of two consecutive cases will be separated by a blank line.


Sample Input
1
6 -45 22 42 -16 -41 -27 56 30 -36 53 -37 77 -36 30 -75 -46 26 -38 -10 62 -32 -54 -6 45
Sample Output
5


Sample Explanation: Indeed, the sum of the ?ve following quadruplets is zero: (-45, -27, 42, 30), (26, 30, -10, -46), (-32, 22, 56, -46), (-32, 30, -75, 77), (-32, -54, 56, 30).

这道题的意思大概是给定四个数组,分别从中取出一个数字,四个数相加为零.

 

lower_bound( )和upper_bound( )都是利用二分查找的方法在一个排好序的数组中进行查找的。

在从小到大的排序数组中,

lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

在从大到小的排序数组中,重载lower_bound()和upper_bound()

lower_bound( begin,end,num,greater<type>() ):从数组的begin位置到end-1位置二分查找第一个小于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

upper_bound( begin,end,num,greater<type>() ):从数组的begin位置到end-1位置二分查找第一个小于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

参考文章:https://blog.csdn.net/qq_40160605/article/details/80150252 

//:(
#include<bits/stdc++.h>
using namespace std;
const int maxn = 4000 + 5;
int n, c, A[maxn], B[maxn], C[maxn], D[maxn], sums[maxn*maxn];
 
int main() 
    int T;
    scanf("%d", &T);
    while (T--) 
        scanf("%d", &n);
        for (int i = 0; i < n; i++)
            scanf("%d%d%d%d", &A[i], &B[i], &C[i], &D[i]);
        c = 0;
        for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            sums[c++] = A[i] + B[j];
        sort(sums, sums + c);
        long long cnt = 0;
        for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            cnt += upper_bound(sums, sums + c, -C[i] - D[j]) - lower_bound(sums, sums + c, -C[i] - D[j]);
        printf("%lld\n", cnt);
        if (T) printf("\n");
    
    return 0;

 

以上是关于UVA1152- 枚举 /二分查找的主要内容,如果未能解决你的问题,请参考以下文章

UVa1152 4 Values whose Sum is 0 (中途相遇法)

UVA 1152 4 Values whose Sum is 0

1152: 二分搜索

UVA-1152-4 Values whose Sum is 0---中途相遇法

UVa-1152 4 Values Whose Sum Is 0

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