zoukankan      html  css  js  c++  java
  • 4 Values whose Sum is 0 POJ 2785 (折半枚举)

    题目链接

    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 -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个整数的四个数列A,B,C,D。要从每个数列中各取出一个数,使四个数的和为0.求出这样的组合的个数,当一个数列中有多个相同的数字时,把它们作为不同的数字看待。

    分析:
    从四个数列中选择的话总共有n^4种情况,所以全部判断一遍不可行。不过将它们对半分成AB和CD再考虑,就可以快速解决了。从两个序列中选择的话只有n^2种组合,所以可以进行枚举。先从A、B中选择a,b后,为了使总和为0,则需要从C,D中取出c+d=-a-b。因此先将从A,B中取数字的n^2种方法全部枚举出来,将这些和排好序,这样就可以运用二分搜索了。

    有时候,问题的规模较大,无法枚举所有元素的组合,但能够枚举一半元素的组合。此时,将问题拆成两半后分别枚举,再合并它们的结果,这一方法往往非常有效。

    代码:

    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    int n,a[4009],b[4009],c[4009],d[4009];
    int num[16000000];
    int main()
    {
        scanf("%d",&n);
        for(int i=0; i<n; i++)
            scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);
        for(int i=0; i<n; i++)
            for(int j=0; j<n; j++)
                num[i*n+j]=a[i]+b[j];
        sort(num,num+n*n);
        long long int ans=0;
        for(int i=0; i<n; i++)
            for(int j=0; j<n; j++)
            {
                int cd=-(c[i]+d[j]);
                ans+=upper_bound(num,num+n*n,cd)-lower_bound(num,num+n*n,cd);
    
            }
        printf("%lld
    ",ans);
    
    
        return 0;
    }
    
  • 相关阅读:
    第四次上课 PPT作业
    大道至简 读后感④
    第三次上课 PPT 课后测试
    大道至简 读后感③
    Java 02 课后作业
    Java 多个数字相加算法
    大道至简 读后感②
    wpf控件
    一个简单的prism mef例子
    c#弱事件(weak event)
  • 原文地址:https://www.cnblogs.com/cmmdc/p/7222135.html
Copyright © 2011-2022 走看看