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 <algorithm>
#include <cstring>
#include <cstdio>
#include <iostream>
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
#define MAXN 4100
#define N 3999971
//#define MOD 10000007
//#define INF 1000000009
//const double eps = 1e-9;
//const double PI = acos(-1.0);

/*
Hash a[] +b[]的和打个表 然后分别用c[] + d[]的和查找
*/
int a[MAXN], b[MAXN], c[MAXN], d[MAXN];
struct edge
{
    int v, next, cnt;
};
edge H[N + 1];
int head[N + 1], k=0;

int Hash(int k)
{
    return (k + N) % N;
}

void add_hash(int val)
{
    int p = Hash(val);
    for (int i = head[p]; i != -1; i = H[i].next)
        if (H[i].v == val)
        {
            H[i].cnt++;
            return;
        }
    H[k].v = val;
    H[k].cnt = 1;
    H[k].next = head[p];
    head[p] = k++;
}

int find_hash(int x)
{
    int p = Hash(x);
    for (int i = head[p]; i != -1; i = H[i].next)
        if (H[i].v == x)
            return H[i].cnt;
    return 0;
}

int main()
{
    int n;    

    while (cin>>n)
    {
        k = 0;
        int i, j;
        LL ans = 0;
        memset(head, -1, sizeof(head));
        for ( i = 0; i < n; i++)
            cin >> a[i] >> b[i] >> c[i] >> d[i];
        for ( i = 0; i < n; i++)
            for ( j = 0; j < n; j++)
                add_hash(a[i] + b[j]);
        for ( i = 0; i < n; i++)
            for ( j = 0; j < n; j++)
                ans += find_hash(-c[i] - d[j]);
        cout << ans << endl;
    }
    return 0;
}

 

 方法2
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<queue>
#include<deque>
#include<iomanip>
#include<vector>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<fstream>
#include<memory>
#include<list>
#include<string>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MAXN 4409
#define N 3999971
#define MOD 10000007
#define INF 1000000009
const double eps = 1e-9;
const double PI = acos(-1.0);

/*
*/
int a[MAXN], b[MAXN], c[MAXN], d[MAXN], n, l1, l2;
vector<int> v1, v2;
int cnt(int x)
{
    int beg = 0, end = l2 - 1;
    while (beg <= end)
    {
        int mid = (beg + end) / 2;
        if (v2[mid] == x)
        {
            int cnt = 1;
            for (int i = mid + 1; i < l2&&v2[i] == x; i++)
                cnt++;
            for (int i = mid - 1; i >= 0 && v2[i] == x; i--)
                cnt++;
            //cout << x <<"at" << mid<< endl;
            return cnt;
        }
        else if (v2[mid] > x)
            end = mid - 1;
        else
            beg = mid + 1;
    }
    
    return 0;
}
int main()
{
    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]);
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                    v1.push_back(a[i] + b[j]);
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                    v2.push_back(-c[i] - d[j]);
        l1 = v1.size(), l2 = v2.size();
        LL ans = 0,pre;
        sort(v2.begin(), v2.end());
        sort(v1.begin(), v1.end());
        for (int i = 0; i < l1; i++)
        {
            if (i && v1[i] == v1[i - 1])
                ans += pre;
            else
                pre = cnt(v1[i]), ans += pre;
        }
        printf("%lld\n", ans);
    }
}

 

posted @ 2017-08-02 16:51  joeylee97  阅读(132)  评论(0编辑  收藏  举报