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 × 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 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 belongrespectively 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 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).

题意

有4个数组,让你从每个数组里找一个数,使得它们的和为0

解析

初想的时候,大家应该和我一样,感觉这道题不难。
既不用什么DP,又不用什么二分(更不可能是图论了),不就是个DFS吗。
但是请看数据规模
别人数据有4000行!
那没办法了。


办法还是有的,那就是折半搜索。

我们把四个数组分成两组
对于前两组,我们挨着枚举,并把他们的和作为下标,方案数作为值存在map里。
对于后两组,我们照样挨着枚举,只要map里有他们的存在,就把ans加上一个相应的值.

代码

这道题因为数据比较大,所以单纯的map会超时,要用哈希

#include<set>
#include<cmath>
#include<cstdio>
#include<vector>
using namespace std;
#define MAXN 9999991
vector < pair<int,int> > Hash[MAXN+5];  
vector <int> a,b,c,d;
int HashAlgorithm(int x){
    return (x%MAXN+MAXN)%MAXN;
}
void Push(int w,int val){
    for(int i=0;i<Hash[w].size();i++)
        if(Hash[w][i].first==val){
            Hash[w][i].second++;
            return;
        }
    Hash[w].push_back(make_pair(val,1));
}
int main(){
    //freopen("data.txt","r",stdin);
    int T;
    bool fir=false; 
    scanf("%d",&T);
    while(T--){
        getchar();
        int n,ans=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            int a1,b1,c1,d1;
            scanf("%d %d %d %d",&a1,&b1,&c1,&d1);
            a.push_back(a1);b.push_back(b1);c.push_back(c1);d.push_back(d1);
        }
        for(int i=0;i<c.size();i++)
            for(int j=0;j<d.size();j++){
                int x=HashAlgorithm(c[i]+d[j]);
                Push(x,c[i]+d[j]);
            }
        for(int i=0;i<a.size();i++)
            for(int j=0;j<b.size();j++){
                int k1=HashAlgorithm(0-a[i]-b[j]);
                for(int k=0;k<Hash[k1].size();k++)
                    if(Hash[k1][k].first==(0-a[i]-b[j])){
                        ans+=Hash[k1][k].second;
                        break;
                    }
            }
        if(fir) puts("");
        else fir=true;
        printf("%d\n",ans);
        for(int i=0;i<=MAXN;i++)
            Hash[i].clear();
        a.clear();b.clear();c.clear();d.clear();
    }
}
posted @ 2018-04-04 14:05  SteinGate  阅读(159)  评论(0编辑  收藏  举报