POJ - 2785(二分)

4 Values whose Sum is 0
Time Limit: 15000MS   Memory Limit: 228000K
Total Submissions: 26497   Accepted: 7979
Case 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 2 28 ) 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 -46
26 -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有几种情况,那么我们知道枚举的话因为n是4000必定超时,那么我们可以开两个数组分别存下来第一第二列数字两两相加的结果,第三第四列数字相加的结果,然后枚举第一个数组来二分查找第二个数组,这样我们就能找到符合题意的情况。

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
using namespace std;
int mapp[4005][5];
int a[16000005];
int b[16000005];
int k;
int erfen(int x)
{
    int mid,l,r,flag=0;
    l=0;
    r=k-1;
    while(l<=r)
    {
        mid=(r+l)/2;
        if(b[mid]==x)
        {
            flag=1;
            break;
        }
        else if(x>b[mid])
            l=mid+1;
        else
            r=mid-1;
    }
    if(flag==1)//找有几种情况,但是因为我们遍历了第一个数组的所有的数,那么这里只要找到一次就要停下来以免查找重复
    {
        int ret=0;
        while(l<k)
        {
            if(b[l]==x)
                ret++;
            else if(b[l]!=x&&ret!=0)
                break;
            l++;
        }
        return ret;
    }
    return -1;
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<4;j++)
        scanf("%d",&mapp[i][j]);
    }
    k=0;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            a[k]=mapp[i][0]+mapp[j][1];
            b[k]=mapp[i][2]+mapp[j][3];
            k++;
        }
    }
    sort(a,a+k);
    sort(b,b+k);
    int sum=0,ans;
    for(int i=0;i<k;i++)
    {
        ans=erfen(-a[i]);
        if(ans!=-1)
            sum+=ans;
    }
    printf("%d\n",sum);
}

猜你喜欢

转载自blog.csdn.net/zezzezzez/article/details/79835311