D - 04

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).

题意:

就是在a,b,c,d四组中分别找出四个数相加,找出相加为0的个数

分析:

简单的用回溯会超时,可以先把这四组变成两组,再用二分

代码:

#include<iostream>
#include<iomanip>
#include<algorithm>
#include<stdio.h>
using namespace std;
long long int a[4005],b[4005],c[4005],d[4005],h[16000005],f[16000005];
int sum=0,n;
void vp(int k)
{
    int l,mid,r,x1,x2;
    long long int x;
    l=0;
    r=n*n-1;
    x=-1*h[k];
    while(l<=r)
    {
        mid=(l+r)/2;
        if(f[mid]<x)
            l=mid+1;
        else
        if(f[mid]>x)
            r=mid-1;
        else
        {
            x1=x2=mid;
            while(f[x1]==x&&x1>=0)
            {
                sum++;
                x1--;
            }
            while(f[x2+1]==x&&x2+1<n*n)
            {
                sum++;
                x2++;
            }
            r=l-1;
        }
    }
}
int main()
{
    int i,k,j;
    scanf("%d",&n);
    for(i=0;i<n;i++)
    scanf("%lld%lld%lld%lld",&a[i],&b[i],&c[i],&d[i]);
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
        h[i*n+j]=a[i]+b[j];
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
        f[i*n+j]=c[i]+d[j];
    sort(h,h+n*n);
    sort(f,f+n*n);
    for(i=0;i<n*n;i++)
        vp(i);
    printf("%d\n",sum);
}
感受:
小错误。。。。让我找了两个小时。。。竟然是因为把=写成了<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值