UVA 4 Values whose Sum is 0 (暴力枚举 + 优化)
题意:给你四个数组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);
}
}