POJ_2785_4 Values whose Sum is 0(lower_bound,upper_bound)

来源:互联网 发布:淘宝联盟账号登不上去 编辑:程序博客网 时间:2024/06/04 08:33
4 Values whose Sum is 0
Time Limit: 15000MS Memory Limit: 228000KTotal Submissions: 16970 Accepted: 4954Case Time Limit: 5000MS

Description

The SUM problem can be formulated as follows: given four lists A, B, C, D of integer values, compute how many quadruplet (a, b, c, d ) ∈ A x B x C x D are such that a + b + c + d = 0 . In the following, we assume that all lists have the same size n .

Input

The first line of the input file contains the size of the lists n (this value can be as large as 4000). We then have n lines containing four integer values (with absolute value as large as 228 ) that belong respectively to A, B, C and D .

Output

For each input file, your program has to write the number quadruplets whose sum is zero.

Sample Input

6-45 22 42 -16-41 -27 56 30-36 53 -37 77-36 30 -75 -4626 -38 -10 62-32 -54 -6 45

Sample Output

5

Hint

Sample Explanation: Indeed, the sum of the five following quadruplets is zero: (-45, -27, 42, 30), (26, 30, -10, -46), (-32, 22, 56, -46),(-32, 30, -75, 77), (-32, -54, 56, 30).


题意:题目给定一个n*4的矩阵,然后问你在每一列中选取一个数,使得四个数之和为0的组合有多少。

分析:折半枚举,双向搜索。题目数据量比较大,暴力肯定超时。所以我们必须另寻它法。我们可以先预处理出AB[k]=A[i]+B[j],CD[k]=C[i]+D[j],然后对CD数组排序(sort(CD,CD+k)),然后枚举AB数组的元素,在CD数组上进行二分搜索就可以了。若在CD数组里存在对应的数,那么就加上这个数的个数,怎么得到这个数的个数?这里就可以巧妙地运用STL库里的两个函数了:lower_bound(),upper_bound()。关于这两个函数的详细解释在:http://blog.csdn.net/jhgkjhg_ugtdk77/article/details/46229645

题目链接:http://poj.org/problem?id=2785

代码清单:

#include<set>#include<map>#include<cmath>#include<queue>#include<stack>#include<ctime>#include<cctype>#include<string>#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef unsigned int uint;const int maxn = 4000 + 5;int n;int A[maxn],B[maxn];int C[maxn],D[maxn];int A_B[maxn*maxn],C_D[maxn*maxn];void input(){    scanf("%d",&n);    for(int i=0;i<n;i++){        scanf("%d%d%d%d",&A[i],&B[i],&C[i],&D[i]);    }}void solve(){    int index=0;    for(int i=0;i<n;i++){        for(int j=0;j<n;j++){            A_B[index]=A[i]+B[j];            C_D[index]=C[i]+D[j];            index++;        }    }    sort(C_D,C_D+index);    ll ans=0;    for(int i=0;i<index;i++){        int number=-A_B[i];        ans+=(ll)(upper_bound(C_D,C_D+index,number)-lower_bound(C_D,C_D+index,number));    }    printf("%I64d\n",ans);}int main(){    input();    solve();    return 0;}


0 0