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 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 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).
解题思路:
枚举并存储A+B的和,然后枚举C+D,搜索-C-D的个数,问题的关键是如何存储A+B的和。本题数据量不小,极限数据n=4000时,A+B的和有16,000,000个,数组显然开不下。那么不妨建立哈希表来存储。
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <set> 6 #include <vector> 7 #include <ctime> 8 #define H 1000000 9 #define maxn 4000 10 #define time__ cout<<" time: "<<double(clock())/CLOCKS_PER_SEC<<endl; 11 using namespace std; 12 vector<int> Hash2[H]; 13 14 int A[maxn+5]; 15 int B[maxn+5]; 16 int C[maxn+5]; 17 int D[maxn+5]; 18 int n; 19 inline void Hash_clear(){ 20 for(int i=0;i<H;i++) 21 Hash2[i].clear(); 22 } 23 inline int h(int x){ 24 return abs(x%H); 25 } 26 inline int count_(int x){ 27 28 int h_=h(x); 29 int cnt=0; 30 for(int i=0;i<Hash2[h_].size();i++) 31 if(Hash2[h_][i]==x) cnt++; 32 return cnt; 33 34 } 35 int main(int argc, const char * argv[]) { 36 37 int T; 38 scanf("%d",&T); 39 while (T--) { 40 Hash_clear(); 41 42 int cnt=0; 43 scanf("%d",&n); 44 for(int i=0;i<n;i++) 45 scanf("%d%d%d%d",&A[i],&B[i],&C[i],&D[i]); 46 for(int i=0;i<n;i++) 47 for(int j=0;j<n;j++){ 48 int x=A[i]+B[j]; 49 50 Hash2[h(x)].push_back(x); 51 52 } 53 for(int i=0;i<n;i++) 54 for(int j=0;j<n;j++){ 55 int x=C[i]+D[j]; 56 cnt+=count_(-x); 57 } 58 cout<<cnt<<endl; 59 if(T) 60 cout<<endl; 61 } 62 //time__; 63 return 0; 64 }