The SUMproblem can be formulated as follows: given four lists A;B;C;D of integer values, compute
how manyquadruplet (a; b; c; d) 2 A_B _C _D are such that a+b+c+d = 0. In thefollowing, we
assume thatall lists have the same size n.
Input
The inputbegins with a single positive integer on a line by itself indicating the numberof the cases
following,each of them as described below. This line is followed by a blank line, andthere is also a
blank linebetween two consecutive inputs.
The _rstline of the input _le contains the size of the lists n (this value can be as large as 4000).
We then haven lines containing four integer values (withabsolute value as large as 228) that belong
respectivelyto A;B;C and D.
Output
For eachtest case, your program has to write the number quadruplets whose sum is zero.
The outputsof two consecutive cases will be separated by a blank line.
Sample Input
1
6
-45 22 42-16
-41 -27 5630
-36 53 -3777
-36 30 -75-46
26 -38 -1062
-32 -54 -645
Sample Output
5
Sample Explanation: Indeed,the sum of the _ve following quadruplets is zero: (-45, -27, 42, 30),
(26, 30, -10,-46), (-32, 22, 56, -46), (-32, 30, -75, 77), (-32, -54, 56, 30).
给四个序列,每个序列选一个数, 求其和为0的情况总数。
如果直接枚举每一个序列, 其复杂度为O(n^4), 按照数据规模 n<=4000,显然会超时
可以将序列两两合并, 转化为两个4000*4000的, 再枚举其中一个的所有元素x, 在另一个中用二分查找 (–x) 的个数即可
注: 查找的是 (–x) 的个数, 所以可以先找出其下标, 在往其两边找。
另外,读题千万仔细,不要问我为什么, 比如:
This line is followed by a blank line, andthere is also a
blank linebetween two consecutive inputs.
#include<bits/stdc++.h> using namespace std; int book[4000*4000 + 2]; int serch(int x, int l, int r){ if(l > r) return -1; int q = (l+r)/2; if(x == book[q]) return q; if(x > book[q]) return serch(x, q+1, r); if(x < book[q]) return serch(x, l, q-1); } int main(){ int T,i,j,t,ans,n; int a1[4002], a2[4002], a3[4002], a4[4002]; cin>>T; while(T--){ cin>>n; for(i=0; i<n; i++) cin>>a1[i]>>a2[i]>>a3[i]>>a4[i]; t = 0; for(i=0; i<n; i++) for(j=0; j<n; j++) book[t++] = a1[i] + a2[j]; sort(book, book + t); ans = 0; int tmp; for(i=0; i<n; i++) for(j=0; j<n; j++) if( (tmp = serch(-a3[i]-a4[j], 0, t-1) ) != -1){ ans++; int h; for(h=1; tmp+h<t && tmp+h>=0 && book[tmp+h]==-a3[i]-a4[j]; h++); ans += h-1; for(h=1; tmp-h<t && tmp-h>=0 && book[tmp-h]==-a3[i]-a4[j]; h++); ans += h-1; } cout<<ans<<endl; if(T) cout<<endl; } }