题目描述
给出4个整数集合A B C D,每个数据集合有n个元素,分别从A B C D中选出一个元素a b c d,使得a+b+c+d=0,问:一共有多少种组合?
输入格式
第一行表示每个集合中的元素数n(0<n<4000)
接下来n行,每行是用空格隔开的4个整数(范围-2^28<a,b,c,d<2^28),分别属于A B C D
输出格式
一行
使得a+b+c+d=0的组合数
输入输出样例
输入样例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
输出样例1:
5
说明
样例1说明:
满足条件的5种组合分别是:
(-45, -27, 42, 30), (26, 30, -10, -46), (-32, 22, 56, -46),(-32, 30, -75, 77), (-32, -54, 56, 30)
【耗时限制】15000ms 【内存限制】256MB
//
//Created by Carlgood.
//
//Note:This program is written in version DEV-C++ 5.11.
# include <iostream>
# include<cmath>
# include<string>
# include<cstring>
# include<cstdio>
# include<algorithm>
# include<sstream>
# include<vector>
# define This_program_is_written_by_Carlgood_Programming_Studio 9876543210
using namespace std;
const int N=4e3+10;
int a[N],b[N],c[N],d[N],ab[N*N],cd[N*N];
int down(int l,int r,int x)
{
while(l<r)
{
int m=(l+r)/2;
if(cd[m]>=x)
{
r=m;
}
else
{
l=m+1;
}
}
return l;
}
int up(int l,int r,int x)
{
while(l<r)
{
int m=(l+r)/2;
if(cd[m]<=x)
{
l=m+1;
}
else
{
r=m;
}
}
return l;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i]>>b[i]>>c[i]>>d[i];
}
sort(a+1,a+n+1);
int cnt=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
ab[++cnt]=a[i]+b[j];
}
}
int CNT=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cd[++CNT]=c[i]+d[j];
}
}
sort(cd+1,cd+CNT+1);
int ans=0;
for(int i=1;i<=cnt;i++)
{
int UP=up(1,CNT+1,0-ab[i]);
int DOWN=down(1,CNT+1,0-ab[i]);
ans+=UP-DOWN;
}
cout<<ans;
return 0;
}