zoukankan      html  css  js  c++  java
  • HDU 4334(思维+二分答案)


    题面:

    Trouble

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 6560    Accepted Submission(s): 1847


    Problem Description
    Hassan is in trouble. His mathematics teacher has given him a very difficult problem called 5-sum. Please help him.
    The 5-sum problem is defined as follows: Given 5 sets S_1,...,S_5 of n integer numbers each, is there a_1 in S_1,...,a_5 in S_5 such that a_1+...+a_5=0?
     

    Input
    First line of input contains a single integer N (1≤N≤50). N test-cases follow. First line of each test-case contains a single integer n (1<=n<=200). 5 lines follow each containing n integer numbers in range [-10^15, 1 0^15]. I-th line denotes set S_i for 1<=i<=5.
     

    Output
    For each test-case output "Yes" (without quotes) if there are a_1 in S_1,...,a_5 in S_5 such that a_1+...+a_5=0, otherwise output "No".
     

    Sample Input
    221 -11 -11 -11 -11 -131 2 3-1 -2 -34 5 6-1 3 2-4 -10 -1
     

    Sample Output
    NoYes
     

    Source

        题目描述:有5个集合,每个集合有n个数,问你从每个集合中取出一个数,取出的五个数的和能否为0。

        题目分析:试着分析下这道题的时间复杂度。如果我们暴力去解题的话,时间复杂度为N*n^5,故极限时间必定超过1e9。故大暴力是绝对不可行的。
        而因为题目让我们求五个数的和,因此我们可以适当进行拆分。
        我们可以先使前两个集合求和,第3、4集合求和,并将这两个新的集合排序,此时,对于最后一个集合,我们就可以通过二分答案的方法去查找是否存在解。
        因为新集合A和新集合B是具有单调性的,因此,我们只需要先从头开始对集合5进行枚举,同时对新集合A进行枚举,最后再对新集合B从最后开始枚举,根据单调性,如果满足e[i]+A[j]+B[k]>0则令B的下标-1,直到满足小于或者等于停止。(等于0则输出yes即可)

        ps:这一题事实上是hdu-1895的简化版,在hdu1895这题中还要求求出满足等于0的个数。
        
        具体看代码:
    #include <bits/stdc++.h>
    #define maxn 2550
    using namespace std;
    typedef long long ll;
    ll a[maxn],b[maxn],c[maxn],d[maxn],e[maxn];
    vector<ll>tmp1,tmp2,tmp3;
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--){
            int n;
            tmp1.clear(),tmp2.clear();
            scanf("%d",&n);
            for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
            for(int i=1;i<=n;i++) scanf("%lld",&b[i]);
            for(int i=1;i<=n;i++) scanf("%lld",&c[i]);
            for(int i=1;i<=n;i++) scanf("%lld",&d[i]);
            for(int i=1;i<=n;i++) scanf("%lld",&e[i]);
    
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    tmp1.push_back(a[i]+b[j]);
                    tmp2.push_back(c[i]+d[j]);
                }
            }
            sort(tmp1.begin(),tmp1.end());
            sort(tmp2.begin(),tmp2.end());
            bool vis=true;
            for(int i=1;i<=n;i++){
                int p=tmp2.size()-1;
                for(int j=0;j<tmp1.size()&&p>=0;j++){
                    while(e[i]+tmp1[j]+tmp2[p]>0) p--;
                    if(e[i]+tmp1[j]+tmp2[p]==0){
                        vis=false;
                        puts("Yes");
                        break;
                    }
                }
                if(!vis) break;
            }
            if(vis) puts("No");
        }
        return 0;
    }
    

  • 相关阅读:
    C#删除一个字符串数组中的空字符串
    .Net后台获取客户端信息
    Java Script
    ECMAScript闭包,ECMAScript对象
    Java Script函数、变量、对象
    JavaScript3
    JavaScript-2
    变量
    8.22收获
    html
  • 原文地址:https://www.cnblogs.com/Chen-Jr/p/11007291.html
Copyright © 2011-2022 走看看