- 原题如下:
4 Values whose Sum is 0
Time Limit: 15000MS Memory Limit: 228000K Total Submissions: 29246 Accepted: 8887 Case Time Limit: 5000MS Description
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 228 ) 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). - 题解:从4个数列中选择的话共有n4种情况,如果全都判断一遍肯定不可行,但如果将它们对半分成AB和CD再考虑,就可以快速解决了。从2个数列种选择的话只有n2种组合,所以可以进行枚举,先从A,B中取出a,b后,为了使总和为0则需要从C,D中取出c+d=-a-b,因此先将从C,D中取出数字的n2种方法全都枚举出来,将这些和排好序,这样就可以二分搜索了,复杂度O(n2logn).
- 代码:
1 #include <cstdio> 2 #include <cctype> 3 #include <algorithm> 4 #include <cmath> 5 #include <cstring> 6 #define number s-'0' 7 8 using namespace std; 9 10 const int MAX_N=5000; 11 int A[MAX_N], B[MAX_N], C[MAX_N], D[MAX_N]; 12 int CD[MAX_N*MAX_N]; 13 int N; 14 15 void read(int &x){ 16 char s; 17 x=0; 18 bool flag=0; 19 while(!isdigit(s=getchar())) 20 (s=='-')&&(flag=true); 21 for(x=number;isdigit(s=getchar());x=x*10+number); 22 (flag)&&(x=-x); 23 } 24 25 void write(int x) 26 { 27 if(x<0) 28 { 29 putchar('-'); 30 x=-x; 31 } 32 if(x>9) 33 write(x/10); 34 putchar(x%10+'0'); 35 } 36 37 double calc(int); 38 39 int main() 40 { 41 read(N); 42 for (int i=0; i<N; i++) 43 { 44 read(A[i]);read(B[i]);read(C[i]);read(D[i]); 45 } 46 for (int i=0; i<N; i++) 47 for (int j=0; j<N; j++) 48 CD[i*N+j]=C[i]+D[j]; 49 sort(CD,CD+N*N); 50 long long res=0; 51 for (int i=0; i<N; i++) 52 for (int j=0; j<N; j++) 53 { 54 int cd=-(A[i]+B[j]); 55 res+=upper_bound(CD, CD+N*N, cd)-lower_bound(CD, CD+N*N, cd); 56 } 57 printf("%d ", res); 58 }