思路:
将a,b,c,d 分为a+b 为 -c-d,然后通过二分查找,对比二者是否相等,若相等则满足 a+b+c+d=0
为了解决二分查找中有重复的值,可以使用upper_bound(第一个大于)和lower_bound(第一个大于等于)分别找一次,然后取差就行。
代码:
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
const int maxn=4010*4010; //n最大4010,a+b或c+d的情况最多有n*n种
int main()
{
int t,n,flag=0;
cin>>t;
while(t--)
{
if(!flag) flag=1;
else cout<<endl;
cin>>n;
ll a[maxn],b[maxn],c[maxn],d[maxn],x[maxn],y[maxn],cnt=0,ans=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++)
{
x[cnt]=a[i]+b[j]; //a+b存入数组x
y[cnt++]=-c[i]-d[j]; //c+d存入数组y
}
sort(x,x+cnt); //x 和 y都排序
sort(y,y+cnt);
for(int i=0;i<cnt;i++)
{
int l=lower_bound(y,y+cnt,x[i])-y; //第一个大于等于x[i]的值
int r=upper_bound(y,y+cnt,x[i])-y; //第一个大于x[i]的值
ans+=r-l;
}
cout<<ans<<endl;
}
return 0;
}