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 .
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 .
For each input file, your program has to write the number quadruplets whose sum is zero.
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
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).
思路:枚举所有的话是4000^4,数据太大,肯定要拆分,然后二分查找;分别分成letf[] 和 right[]两个数组;
代码如下:
#include <stdio.h>
#include <algorithm>
using namespace std;
int left[16000005] , right[16000005];
struct node{
int a, b, c, d;
}s[4005];
int main() {
int n;
scanf("%d",&n);
for(int i = 0; i < n; i++) {
scanf("%d %d %d %d",&s[i].a, &s[i].b, &s[i].c, &s[i].d);
}
int t = 0;
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
left[t] = s[i].a + s[j].b;
right[t] = s[i].c + s[j].d;
t++;
}
}
int sum = 0;
sort(left , left + t);
for(int i = 0; i < t; i++) {
sum += upper_bound(left,left+t,-right[i])-lower_bound(left,left+t,-right[i]);
}
printf("%d\n",sum);
return 0;
}
upper_bound(a , a+n , m)返回第一个大于m的位置;
lower_bound(a , a+n , m)返回第一个大于等于m的位置;
以上两者类似于二分找到答案;