题意:给你四个数组A,B,C,D,从四个数组分别取一个数he进行组合,判断其和是否为0,计算出这样的组合的个数
思路:4重暴力枚举时间复杂度O(n^4),必定超时,这里我们首先枚举A,B,用一个数组S1存两个数组中的每两个数的和,
再枚举C,D;用一个数组S2存这个数组中的每两个数的和的相反数,然后只需枚举S1和S2,找出S1中的数与S2中的数相
同的个数,但是暴力枚举会超时,所以要用二分查找,时间复杂度时O(n^2*logn)
代码:
#include <map> #include <set> #include <cmath> #include <queue> #include <stack> #include <cstdio> #include <vector> #include <iomanip> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define ll long long #define mod 1000000007 #define mem(a) memset(a,0,sizeof(a)) using namespace std; const int maxn = 4000 + 5, inf = 0x3f3f3f3f; int A[maxn],B[maxn],C[maxn],D[maxn],S1[maxn*maxn],S2[maxn*maxn] , n ; int main(){ // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int kase , ikase = 0; scanf("%d",&kase); while(kase--){ scanf("%d",&n); mem(A);mem(B);mem(C);mem(D);mem(S1);mem(S2) ; for(int i = 0 ; i < n ; i ++ ) scanf("%d %d %d %d",&A[i],&B[i],&C[i],&D[i]) ; int k = 0 ; for(int i = 0 ; i < n ; i ++ ) for(int j = 0 ; j < n ; j ++ ) S1[k++] = A[i] + B[j] ; k = 0; for(int i = 0 ; i < n ; i ++) for(int j = 0 ; j < n ; j ++ ) S2[k++] = -(C[i] + D[j]); sort(S1,S1+k); sort(S2,S2+k); int cnt = 0; for(int i = 0 ; i < k ; i ++ ){ int p1 = lower_bound(S2,S2+k,S1[i]) - S2; int p2 = upper_bound(S2,S2+k,S1[i]) - S2; cnt += (p2 - p1);//计算S2中有多少和S1[i]相同的 } if(ikase++>0) printf("\n"); printf("%d\n",cnt); } }