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;
    }
    

  • 相关阅读:
    Angular Universal 学习笔记
    SAP Spartacus 如何获得当前渲染页面的 CMS 元数据
    Angular 服务器端渲染的学习笔记(二)
    Angular 服务器端渲染的学习笔记(一)
    第三方外部 Saas提供商如何跟使用 SAP 系统的客户进行对接接口集成
    如何从 SAP Spartacus Product Detail 页面,找到其 Angular 实现 Component 的位置
    具备自动刷新功能的 SAP ABAP ALV 报表
    C++学习目录
    c--条件编译
    c--文件读写--二进制
  • 原文地址:https://www.cnblogs.com/Chen-Jr/p/11007291.html
Copyright © 2011-2022 走看看