zoukankan      html  css  js  c++  java
  • (POJ 2549)Sumsets(折半枚举)

    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


    看数据范围想想就知道暴力不可行,这几天心血了另外一种枚举方法,折半枚举。
    因为a+b+c=d;
    所以式子可以化为a+b=d-c;
    所以把暴力枚举的o(n^4)变成o(n^2);
    先把所有的a+b枚举出来,用map记录其是否出现过,再枚举d-c,看看其对应的数字有没有出现。因为还要判断abcd互不相同,所以枚举时要注意条件。
    PS:由于a+b可以小于0,用map方便一点。

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<set>
    #include<map>
    #include<string.h>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #define inf 0x3f3f3f3f
    
    using namespace std;
    int a[1010];
    int n;
    
    class po
    {
    public:
        int a,b;
        po(int a1,int b1){a=a1,b=b1;}
    };
     map<int,vector<po> > run;
    
    
    
    int solve()
    {
         for(int i=n;i>=1;i--)
                {
                    for(int j=1;j<=n;j++)
                    {
                        if(j==i)
                            continue;
                        int tem=a[j]-a[i];
                        for(int k=0;k<run[tem].size();k++)
                        {
                           // cout << a[i] << " " << a[j] << endl;
                            int a1=run[tem][k].a;
                            int b1=run[tem][k].b;
                            if(a[i]!=a1&&a[i]!=b1&&a[j]!=a1&&a[j]!=b1)
                                return a[j];
                        }
                    }
                }
        return 536870912;
    }
    
    int main()
    {
        while(~scanf("%d",&n))
        {
            if(n==0)
                break;
            run.clear();
            memset(a,0,sizeof(a));
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            sort(a+1,a+1+n);
            for(int i=1;i<=n;i++)
            {
                for(int j=i+1;j<=n;j++)
                {
                    po tem(a[i],a[j]);
                    run[a[j]+a[i]].push_back(tem);
                }
            }
           int ans=solve();
           if(ans==536870912)
            printf("no solution
    ");
           else
            printf("%d
    ",ans);
        }
        return 0;
    }
    此地非逐弃者之王座,彼方乃行愿者之归所。无限清澈,星界银波。
  • 相关阅读:
    DBHelper类
    户籍不在本市并已申请基本养老保险或基本医疗保险关系转移手续销户提取业务办理指南(试行)
    Android 打开/播放电脑的音频/视频文件
    (技术贴)如何鉴定绿茶婊
    Swift初探(一)
    关于android移动终端IM的一些问题
    C++中对象、引用、指针
    TextView
    新API
    开发者必备的6款源码搜索引擎
  • 原文地址:https://www.cnblogs.com/brotherHaiNo1/p/7306298.html
Copyright © 2011-2022 走看看