给出四个数组 A , B , C , D A,B,C,D A,B,C,D ,每个数组中有 n n n 个整数。求有多少组 i , j , k , l i,j,k,l i,j,k,l 满足 A i + B j + C k + D l = 0 A_i+B_j+C_k+D_l=0 Ai+Bj+Ck+Dl=0 。
本题有多组测试数据。
第一行一个正整数 T T T ,表示数据组数。
对于每组数据:
第一行一个整数 n n n 。
接下来 n n n 行,一行四个整数,分别表示 A i , B i , C i , D i A_i,B_i,C_i,D_i Ai,Bi,Ci,Di 。
共 2 × T 2\times T 2×T 行。
对于每组数据:
第一行一个整数,表示该组测试数据的答案。
接下来输出一个空行。
1 ≤ n ≤ 4000 1\le n\le4000 1≤n≤4000 。数组中所有数的绝对值不大于 2 28 2^{28} 228 。
1
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
题目让我们求 A + B + C + D = 0 A+B+C+D=0 A+B+C+D=0,我们可以把将 C + D C+D C+D移到右边,变成 A + B = − C − D A+B=-C-D A+B=−C−D,这样我们就可以枚举所有的 A + B A+B A+B,把它放入一个映射数组中,再枚举所有的 − C − D −C−D −C−D,看该映射中有过多少次该值。
#include
using namespace std;
#include //麻烦的头文件,为什么万能头里没有?
#include
using namespace __gnu_pbds;
gp_hash_table <int,int> g;//mapTLE了
int a[10000],b[10000],c[10000],d[10000];
int T;
int n;
int ans;
int main()
{
cin>>T;
while(T--)
{
ans=0;
g.clear();
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i]>>b[i]>>c[i]>>d[i];
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
int k=a[i]+b[j];
g[k]++;
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
int k=c[i]+d[j];
ans+=g[-k];
}
}
cout<<ans<<endl;
if(T>0)
{
cout<<endl;
}
}
return 0;
}