zoukankan      html  css  js  c++  java
  • POJ 2549 Sumsets

    Sumsets
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 10593   Accepted: 2890

    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
    

    Source

     
     
     
    解析:折半枚举。之前碰到的折半枚举都是将集合折半,这次不同,折半的思想体现在等式上。将等式a + b + c = d转化为a + b = d - c,等式分成左右两部分,预处理出左右两部分,将左半部分排序,然后枚举右半部分,二分查找即可。时间复杂度为O(n2logn2)。
     
     
     
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    const int MAXN = 1000+5;
    int n;
    int a[MAXN];
    
    struct S{
        int val;
        int i, j;
        bool operator < (const S& b)const
        {
            return val < b.val;
        }
    };
    S l[MAXN*MAXN], r[MAXN*MAXN];
    
    bool ok(S& a, S& b)
    {
        return a.i != b.i && a.j != b.j && a.i != b.j && a.j != b.i;
    }
    
    void solve()
    {
        int lcnt = 0;
        for(int i = 0; i < n; ++i){
            for(int j = i+1; j < n; ++j){
                l[lcnt].val = a[i]+a[j];
                l[lcnt].i = i;
                l[lcnt++].j = j;
            }
        }
        int rcnt = 0;
        for(int i = 0; i < n; ++i){
            for(int j = i+1; j < n; ++j){
                r[rcnt].val = a[i]-a[j];
                r[rcnt].i = i;
                r[rcnt++].j = j;
                r[rcnt].val = a[j]-a[i];
                r[rcnt].i = j;
                r[rcnt++].j = i;
            }
        }
        sort(l, l+lcnt);
        int res = 0xffffffff;
        for(int i = 0; i < rcnt; ++i){
            int d = lower_bound(l, l+lcnt, r[i])-l;
            if(ok(l[d], r[i]) && l[d].val == r[i].val){
                res = max(res, r[i].val+a[r[i].j]);
            }
        }
        if(res == 0xffffffff)
            printf("no solution
    ");
        else
            printf("%d
    ", res);
    }
    
    int main()
    {
        while(scanf("%d", &n), n){
            for(int i = 0; i < n; ++i)
                scanf("%d", &a[i]);
            solve();
        }
        return 0;
    }
    

      

  • 相关阅读:
    log4net详细配置说明
    step by step 之餐饮管理系统三
    CF div2 331 C
    CF div2 331 B
    CF div2 331 A
    poj 2065 还是gauss消元
    poj 3478 poj 3090(欧拉函数的应用)
    poj 1284 求原根的个数(欧拉函数的应用)
    poj 2991 线段树
    poj 1753 poj3185
  • 原文地址:https://www.cnblogs.com/inmoonlight/p/5788954.html
Copyright © 2011-2022 走看看