给出a, b, c, d四组数,从它们之中各取出一个数,使得这4个数的和为零,求这样组合的个数。如果一列中有相同的数字,将它们当成不同的看。
http://poj.org/problem?id=2785
数据范围大,不能O(n^4)。
先枚举出c和d的组合情况,放入数组cd,将其排序。
再枚举a和b组合的情况,并从cd中二分出结果。
这样复杂度就变成O(nlogn)
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 4000 + 10;
int n, a[maxn], b[maxn], c[maxn], d[maxn], cd[maxn * maxn];
int main(){
scanf("%d", &n);
for(int i=0; i<n; i++) scanf("%d%d%d%d", &a[i], &b[i], &c[i], &d[i]);
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
cd[i * n + j] = c[i] + d[j];
sort(cd, cd + n * n);
long long ans = 0;
for(int i=0; i<n; i++)
for(int j=0; j<n; j++){
int ab = -(a[i] + b[j]);
ans += upper_bound(cd, cd + n * n, ab) - lower_bound(cd, cd + n * n, ab);
}
printf("%I64d\n", ans);
return 0;
}