• 折半枚举(双向搜索)poj27854 Values whose Sum is 0


    4 Values whose Sum is 0
    Time Limit: 15000MS   Memory Limit: 228000K
    Total Submissions: 23757   Accepted: 7192
    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 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).

    Source

    [Submit]   [Go Back]   [Status]   [Discuss]


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


    //折半枚举(双向搜索)poj2785
    #include <iostream>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn=5005;
    int n;
    ll a[maxn],b[maxn],c[maxn],d[maxn];
    ll cd[maxn*maxn];
    
    
    void solve()
    {
        //枚举cd的组合
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                cd[i*n+j]=c[i]+d[j];
            }
        }
        sort(cd,cd+n*n);
        ll res=0;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                ll CD=-(a[i]+b[j]);
                //二分搜索取出cd中和为CD的部分
                res+=upper_bound(cd,cd+n*n,CD)-lower_bound(cd,cd+n*n,CD);
            }
        }
        printf("%lld
    ",res);
    }
    
    int main()
    {
        cin>>n;
        for(int j=0;j<n;j++)
        {
            cin>>a[j]>>b[j]>>c[j]>>d[j];
        }
        solve();
        return 0;
    }
    


  • 相关阅读:
    Flash、Ajax各自的优缺点,在使用中如何取舍?
    纯CSS气泡框实现方法探究
    CSS里padding和margin的区别是什么?
    img图片标签alt和title属性的区别
    JS中都有哪些数据类型呢?
    剑指offer---按只字形顺序打印二叉树
    剑指offer---序列化二叉树
    剑指offer---二叉树的下一个结点
    剑指offer---二叉树的深度
    剑指offer---平衡二叉树
  • 原文地址:https://www.cnblogs.com/bryce1010/p/9387379.html
Copyright © 2020-2023  润新知