zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    POJ 1401 Factorial
    POJ 2407 Relatives(欧拉函数)
    POJ 1730 Perfect Pth Powers(唯一分解定理)
    POJ 2262 Goldbach's Conjecture(Eratosthenes筛法)
    POJ 2551 Ones
    POJ 1163 The Triangle
    POJ 3356 AGTC
    POJ 2192 Zipper
    POJ 1080 Human Gene Functions
    POJ 1159 Palindrome(最长公共子序列)
  • 原文地址:https://www.cnblogs.com/ZefengYao/p/6525240.html
Copyright © 2011-2022 走看看