- 题意:给你一个n行4列的矩阵,从每列选择一个数字,问这四个数字加起来为0的数字组合有多少个?
- 思路:暴力
O(n4)
超时,只有把前两个数字的所有和枚举出来(
O(n2)
),然后排序(
O(nlogn)
),最后枚举最后两数的所有组合,每一个组合用二分查找已经排序好的前两个数字组合(
O(n2logn)
),故总的复杂度是:
O(n2logn)
代码:
#include <set>
#include <map>
#include <cmath>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long int LL;
const int M = 4009,INF = 0x3fffffff;
int n, a[M], b[M], c[M], d[M];
int A[M * M], B[M * M];
int doit(int x, int step) {
int l = 0, r = step , mid = -1, ans = 0;
while(l < r) {
mid = (l + r) / 2;
if(B[mid] == x) {
for(int i = mid - 1; i >= 0; i--) {
if(B[i] != x) break;
ans++;
}
for(int i = mid; i < step; i++) {
if(B[i] != x) break;
ans++;
}
break;
}
if(B[mid] < x) l = mid + 1;
else r = mid;
}
return ans;
}
int main(void) {
while(cin >> n) {
int step = 0;
for(int i = 0; i < n; i++) cin >> a[i] >> b[i] >> c[i] >> d[i];
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
A[step] = a[i] + b[j];
B[step++] = c[i] + d[j];
}
}
sort(B, B + step);
int ans = 0;
for(int i = 0; i < step; i++) {
ans += doit(-A[i], step);
}
cout << ans << endl;
}
return 0;
}