• Sumsets


                                                                                                                                                       Sumsets
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 11046   Accepted: 3024

    Description

    Given S, a set of integers, find the largest d such that a + b + c = d where a, b, c, and d are distinct elements of S.

    Input

    Several S, each consisting of a line containing an integer 1 <= n <= 1000 indicating the number of elements in S, followed by the elements of S, one per line. Each element of S is a distinct integer between -536870912 and +536870911 inclusive. The last line of input contains 0.

    Output

    For each S, a single line containing d, or a single line containing "no solution".

    Sample Input

    5
    2 
    3 
    5 
    7 
    12
    5
    2 
    16 
    64 
    256 
    1024
    0
    

    Sample Output

    12
    no solution

    题意:给定n个数组成一个集合S,从S中找到一个数d以及a,b,c,使得d=a+b+c,现在要挑选出最大的d满足上述条件,如果没有找到,输出'no solution'
    思路:将等式改为a+b=d-c,对于等式的左右两边,第一步:可以分别枚举出所有可能的情况,第二步:对于等式左边的每一种情况,在等式右边进行二分搜索,搜索出所有和等式左边的和值相等的所有情况,不断的更新d值即可。
    需要注意的是集合S中的每个元素不能重复的使用,只能使用一次,所以在第二步中对等式右边搜索出来的情况还需要进行筛选操作,如果等式右边的元素与左边重复了,就需要舍弃这种情况!!
    AC代码:
    #define _CRT_SECURE_NO_DEPRECATE
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<functional>
    using namespace std;
    typedef long long ll;
    const int N_MAX = 1000 + 4;
    int n;
    ll S[N_MAX];
    struct Set {
        ll sum;
        int i, j;
        Set(ll s,int a,int b):sum(s),i(a),j(b) {}
        bool operator <(const Set&b)const {
            return sum < b.sum;
        }
        bool operator >(const Set&b)const {//!!!!!!!
            return sum > b.sum;
        }
        bool operator != (const Set&b)const {
            return (i != b.i&&i != b.j&&j != b.j&&j != b.i);//!!!!!
        }
    };
    
    
    int main() {
        
        while (scanf("%d",&n)&&n) {
            for (int i = 0; i < n; i++) {
                scanf("%lld",&S[i]);
            }
            vector<Set>Left;
            vector<Set>Right;
            for (int i = 0; i < n; i++) {
                for (int j = i + 1; j < n; j++) {
                    Left.push_back(Set(S[i]+S[j],i,j));
                }
          }
            for (int i = 0; i < n; i++) {
                for (int j = i + 1; j < n; j++) {
                    Right.push_back(Set(S[i]-S[j],i,j));
                    Right.push_back(Set(S[j] - S[i], j, i));//!!!!!!!!!!!!!两种情况都要算上
                }
            }
            sort(Left.begin(),Left.end());//有序排列再进行二分搜索!!!!!!!!!!!!
            sort(Right.begin(),Right.end());
            ll res=-INT_MAX ;
            for (vector<Set>::const_iterator it = Left.begin(); it != Left.end(); it++) {//对于左侧计算出来的每一个值!!!!!!!!!!!!!!!
                vector<Set>::iterator lb = lower_bound(Right.begin(),Right.end(),*it);//找出右侧与左边和值相等的差
                vector<Set>::iterator ub = upper_bound(lb, Right.end(), *it);/////以lb起始减少查找次数
                for (; lb!=ub;lb++) {
                    if (*it != *lb) {//所取得左右两边的元素都不一样!!!!!!!!!!!!!!!!!!!!!1
                        res = max(res, it->sum+S[lb->j]);
                    }
                 }
            }
            if (res <- 536870912)printf("no solution
    ");
            else printf("%lld
    ",res);
        }
        return 0;
    }
  • 相关阅读:
    SSH防止超时的设置
    vuejs中v-bind绑定class时的注意事项
    js常用到的方法积累
    主流浏览器以及系统的判断
    理解Javascript的状态容器Redux
    可伸缩架构简短系列
    在Node.js中使用RabbitMQ系列一 Hello world
    在Node.js中使用RabbitMQ系列二 任务队列
    Javascript中的async await
    公钥,私钥和数字签名
  • 原文地址:https://www.cnblogs.com/ZefengYao/p/6525240.html
Copyright © 2020-2023  润新知