• 【Poj】2594 Sumsets 折半枚举


    题目链接

    题意

    给出 n 个数字,求满足(a+b+c=d)的 d 的最大值,注意(a,b,c,d) 互不相等。

    思路

    折半枚举。
    首先我们把任意两个数的和求出,排序。

    然后从大到小枚举 d 的值,再枚举 c 的值,对于(d-c),我们二分找到其在两个数的和中出现的次数。

    接下来开始将重复的情况删去。

    有三种情况

    1. (a+b=a-b)
    2. (a+b=a-c)
    3. (a+b=c-b)

    第一种情况可以知道 b=0

    第二种情况可以知道 b=-c

    第三种情况可以知道 a=c-2*b

    那么我们只需要将这三种重复的情况去掉,如果这时次数还大于0,那么就找到了最大的 d。

    退出循环即可。

    代码

    /*
     * @Autor: valk
     * @Date: 2020-08-11 12:38:37
     * @LastEditTime: 2020-09-28 17:19:07
     * @Description: 如果邪恶  是华丽残酷的乐章 它的终场 我会亲手写上 晨曦的光 风干最后一行忧伤 黑色的墨 染上安详
     */
    #include <algorithm>
    #include <iostream>
    #include <map>
    #include <math.h>
    #include <queue>
    #include <set>
    #include <stack>
    #include <stdio.h>
    #include <string.h>
    #include <string>
    #include <vector>
    #define pb push_back
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int mod = 1e9 + 7;
    const int seed = 12289;
    const double eps = 1e-6;
    const int inf = 0x3f3f3f3f;
    const int N = 4e3 + 10;
    
    vector<int>vec,sum;
    map<int,int>mp;
    int main()
    {
        int n;
        while(~scanf("%d",&n)){
            if(!n) break;
            vec.clear(),sum.clear(),mp.clear();
            int x;
            for(int i=1;i<=n;i++){
                scanf("%d",&x);
                mp[x]=1;
                vec.pb(x);
            }
            for(int i=0;i<n;i++){
                for(int j=i+1;j<n;j++){
                    sum.pb(vec[i]+vec[j]);
                }
            }
            sort(vec.begin(),vec.end());
            sort(sum.begin(),sum.end());
            int ans=-inf;
            for(int i=n-1;i>=0;i--){
                for(int j=0;j<n;j++){
    
                    if(i==j) continue;
                    int dis=vec[i]-vec[j];
                    int l=lower_bound(sum.begin(),sum.end(),dis)-sum.begin();
                    int r=upper_bound(sum.begin(),sum.end(),dis)-sum.begin();
                    int num=r-l;
                    if(vec[j]==0) num--;
                    if(mp[-vec[j]]) num--;
                    if(mp[dis-vec[j]]) num--;
                    if(num>0) {
                        ans=vec[i];
                        break;
                    }
                }
                if(ans!=-inf) break;
            }
            if(ans!=-inf) printf("%d
    ",ans);
            else printf("no solution
    ");
        }
        return 0;
    }
    
    
  • 相关阅读:
    【转】#pragma pack(push,1)与#pragma pack(1)的区别
    emwin 之变量定义位置
    【转】C语言字符串与数字相互转换
    【转】用emWin进度条控件做个表盘控件,效果不错
    emwin 之消息 WM_INIT_DIALOG
    emwin 之使用键盘数据发送函数的注意事项
    emwin 解决在A窗口上新建B窗口后‘只激活’B窗口问题
    【转】数学与编程——求余、取模运算及其性质
    hdu4831 Scenic Popularity(线段树)
    2014年百度之星程序设计大赛
  • 原文地址:https://www.cnblogs.com/valk3/p/13773919.html
Copyright © 2020-2023  润新知