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
Inputcopy | Outputcopy |
---|---|
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 |
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).
题目的意思是给四列数字, 然后各选一个相加为零。
正常情况就是写四个循环, 但是四个循环肯定超时, 所以的话我们要首先对这四组数字分开进行处理, 两两相加, 求出所有的情况, 然后再一个循环, 另一个写二分来做, 这样可以不超时, 最后的话在二分里面需要注意相同数字的情况, 所以我们在结束mid的判断时需要继续向上向下判断是否想等, 如果不等立刻break, 自己也是写了很长时间, 主要是debug:
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <string>
using namespace std;
const int N = 4000 * 4000 + 10;
int q[N], p[N]; // ab, cd;
int a[N], b[N], c[N], d[N];
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> a[i] >> b[i] >> c[i] >> d[i];
}
int num = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
q[num] = a[i] + b[j]; //预处理
p[num] = c[i] + d[j];
num ++;
}
}
//sort(q, q + num); // 可以只处理一项, 另外一项用来枚举。
sort(p, p + num);
int res = 0;
for (int i = 0; i < num; i++) {
int l = 0, r = num - 1;
while (l <= r) {
int mid = l + r >> 1;
if (q[i] + p[mid] > 0) r = mid - 1;
else if (q[i] + p[mid] < 0) l = mid + 1;
else {
res ++;
for (int j = mid - 1;j >= 0; j--) { // 相等的情况:
if (q[i] + p[j] == 0) res ++;
else break;
}
for (int j = mid + 1;j < num; j++) {
if (q[i] + p[j] == 0) res ++;
else break;
}
break;
}
}
}
cout <<res;
return 0;
}
加油!