4 Values whose Sum is 0 二分

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 x B x C x D are such that a + b + c + d = 0 . In the following, we assume that all lists have the same size n .

Input

The first line of the input file 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 2 28 ) that belong respectively to A, B, C and D .

Output

For each input file, your program has to write the number quadruplets whose sum is zero.

Sample Input

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

Hint

Sample Explanation: Indeed, the sum of the five following quadruplets is zero: (-45, -27, 42, 30), (26, 30, -10, -46), (-32, 22, 56, -46),(-32, 30, -75, 77), (-32, -54, 56, 30).
 
前后两个数组个元素的和球出来,然后二分搜索求解。
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
#define MAXN 4004
int a[MAXN], b[MAXN], c[MAXN], d[MAXN], sum1[MAXN*MAXN], sum2[MAXN*MAXN];
int main() 
{
    int n;
    while (scanf("%d", &n) != EOF)
    {
        for (int i = 0; i < n; i++)
        {
            scanf("%d%d%d%d", &a[i], &b[i], &c[i], &d[i]);
        }
        int l1, l2;
        l1 = l2 = 0;
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                sum1[l1++] = a[i] + b[j];
                sum2[l2++] = c[i] + d[j];
            }
        }
        sort(sum1, sum1 + l1);
        int ans = 0;
        for (int i = 0; i < l2; i++)
        {
            int beg = 0, end = l1 - 1;
            while (beg <= end)
            {
                int mid = (beg + end) / 2;
                if (sum1[mid]+ sum2[i]==0)
                {
                    ans++;
                    for (int p = mid + 1; p < l1; p++)
                        if (sum1[p] + sum2[i] != 0)
                            break;
                        else
                            ans++;
                    for (int p = mid - 1; p >= 0; p--)
                        if (sum1[p] + sum2[i] != 0)
                            break;
                        else
                            ans++;
                    break;
                }
                if (sum1[mid] + sum2[i]<0)
                    beg = mid + 1;
                else
                    end = mid - 1;
            }
        }
        printf("%d
", ans);
    }
}
原文地址:https://www.cnblogs.com/joeylee97/p/6702241.html