题意:求在四个大小为4000的数列中分别选出一个数相加等于0的情况数。
思路:
如果是直接枚举的话,O(n^4),肯定不行。
可以先预处理出A和B相加情况,排好序;然后枚举出C和 D 相加的情况,然后将二分查找能和CD相加等于0的情况。
复杂度:O(n ^ 2 * log(n ^ 2));
Code:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 4e3 + 10;
#define INF 0x3f3f3f3f
typedef long long ll;
int a[maxn],b[maxn],c[maxn],d[maxn];
int num[maxn * maxn];
int n;
int main()
{
while( ~ scanf("%d",&n))
{
for(int i = 1; i <= n; i ++)
scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);
int len = 0;
for(int i = 1; i <= n;i ++)
{
for(int j = 1 ; j <= n; j ++)
{
num[len ++] = a[i] + b[j];
}
}
sort(num,num + len);
ll ans = 0;
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= n; j ++)
{
int t = -(c[i] + d[j]);
ans += upper_bound(num,num + len,t) - lower_bound(num,num + len,t);
}
}
cout << ans << endl;
}
return 0;
}