题意:给你四个集合,让你从每个集合中挑选一个数字使他们的和为0,问共有多少种方法。
思路:首先四重for循环4000的四次方肯定超时,我们将这四个集合进行两两加和变为两个集合,n^2复杂度,这时我们再枚举一个加和集合的值,然后将另一个加和后的集合排序二分查找答案就行,总复杂度为n^2*log n;注意输出!!!
#include<bits/stdc++.h>
using namespace std;
int n,a[4005],b[4005],c[4005],d[4005],sum1[4005*4005],sum2[4005*4005];
int main()
{
int T;scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);
}
int x=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
sum1[x]=a[i]+b[j];
sum2[x++]=c[i]+d[j];
}
}
sort(sum1,sum1+x);
int count=0;
for(int i=0;i<x;i++)
{
int pos=lower_bound(sum1,sum1+x,-sum2[i])-sum1;
if((sum1[pos]+sum2[i])==0)
{
int pos2=upper_bound(sum1,sum1+x,-sum2[i])-sum1;
count+=(pos2-pos);
}
}
printf("%d\n",count);
if(T>0) printf("\n");
}
return 0;
}