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);
     }
}

猜你喜欢

转载自blog.csdn.net/insist_77/article/details/80260741
今日推荐