题目大意:在4个都有n个元素的集合中,每个集合选出一个元素,使得4个数和为0。问有几种方案。
题目分析:二分。任选两组求和,剩下两组求和,枚举第一组中每一个和sum,在第二组和中查找-sum的个数,累加起来便得答案。
代码如下:
# include<iostream> # include<cstdio> # include<vector> # include<cstring> # include<algorithm> using namespace std; int a[4000][4]; vector<int>v1,v2; int f1(int l,int r,int x)///查找下界 { int lp,m; while(l<r){ m=l+(r-l)/2; if(v2[m]<x){ lp=l=m+1; }else lp=r=m; } return lp; } int f2(int l,int r,int x)///查找上界 { int up,m; while(l<r){ m=l+(r-l)/2; if(v2[m]<=x) up=l=m+1; else up=r=m; } return up; } int main() { int T,n; scanf("%d ",&T); while(T--) { scanf("%d",&n); v1.clear(),v2.clear(); for(int i=0;i<n;++i) for(int j=0;j<4;++j) scanf("%d",&a[i][j]); for(int i=0;i<n;++i){ for(int j=0;j<n;++j){ v1.push_back(a[i][0]+a[j][1]); v2.push_back(a[i][2]+a[j][3]); } } int ans=0; sort(v2.begin(),v2.end()); for(int i=0;i<n*n;++i){ int lpos=f1(0,n*n,-v1[i]); int upos=f2(0,n*n,-v1[i]); ans=ans+upos-lpos; } printf("%d ",ans); if(T) printf(" "); } return 0; }