码迷,mamicode.com
首页 > 其他好文 > 详细

【Poj】2594 Sumsets 折半枚举

时间:2020-10-06 21:16:10      阅读:46      评论:0      收藏:0      [点我收藏+]

标签:can   href   auto   bre   class   clu   tac   ios   poj   

题目链接

题意

给出 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\n",ans);
        else printf("no solution\n");
    }
    return 0;
}

【Poj】2594 Sumsets 折半枚举

标签:can   href   auto   bre   class   clu   tac   ios   poj   

原文地址:https://www.cnblogs.com/valk3/p/13773919.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!