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

Waterloo local 2001.06.02

解析:折半枚举。之前碰到的折半枚举都是将集合折半,这次不同,将等式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\n");
    else
        printf("%d\n", res);
}

int main()
{
    while(scanf("%d", &n), n){
        for(int i = 0; i < n; ++i)
            scanf("%d", &a[i]);
        solve();
    }
    return 0;
}

  

时间: 2024-10-24 23:56:18

POJ 2549 Sumsets的相关文章

POJ 2549 Sumsets hash值及下标

题目大意:找到几何中的4个数字使他们能够组成 a+b+c=d , 得到最大的d值 我们很容易想到a+b = d-c 那么将所有a+b的值存入hash表中,然后查找能否在表中找到这样的d-c的值即可 因为4个数字都不能相同,那么我们同时要在hash表中记录相加两个数的下标,然后查找的时候还要进行下标判断 这里用二分查找也可以,但是能用hash还是hash快地多了 这里第一次写到对负数进行hash,还是傻傻地 val%MOD , 但是负数得到的模值为负,作为hash的下标会RE,所以RE了一发,还是

poj 2549 --- 传说中的用“桶”防止HASH冲突

http://poj.org/problem?id=2549 维基百科有3Sum算法:https://en.wikipedia.org/wiki/3SUM sort(S); for i=0 to n-3 do a = S[i]; k = i+1; l = n-1; while (k<l) do b = S[k]; c = S[l]; if (a+b+c == 0) then output a, b, c; // Continue search for all triplet combinatio

Divide and conquer:Sumsets(POJ 2549)

数集 题目大意:给定一些数的集合,要你求出集合中满足a+b+c=d的最大的d(每个数只能用一次) 这题有两种解法, 第一种就是对分,把a+b的和先求出来,然后再枚举d-c,枚举的时候输入按照降序搜索就好,一旦d满足条件就是最大的了,另外判断不重复存一下位置就好,时间复杂度0(n^2*logn) 1 #include <iostream> 2 #include <functional> 3 #include <algorithm> 4 5 using namespace

poj 2459 Sumsets

Sumsets Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11612   Accepted: 3189 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 cons

poj 2229 Sumsets 完全背包求方案总数

Sumsets Description Farmer John commanded his cows to search for different sets of numbers that sum to a given number. The cows use only numbers that are an integer power of 2. Here are the possible sets of numbers that sum to 7: 1) 1+1+1+1+1+1+1 2)

poj 2220 Sumsets

Sumsets Time Limit: 2000MS   Memory Limit: 200000K Total Submissions: 16876   Accepted: 6678 Description Farmer John commanded his cows to search for different sets of numbers that sum to a given number. The cows use only numbers that are an integer

POJ 2229 Sumsets (递推&amp;整数划分变形)

http://poj.org/problem?id=2229 思路:假设加数按从小到大的顺序.当n为奇数时,第一个数必须为1,此时f(n)=f(n-1):当n为偶数时,分两种情况讨论,若第一个数为1,则f(n)=f(n-1),若第一个数不为奇数,则所有数都不为奇数,提出一个公因子2出来,就是f(n/2),所以,f(n)=f(n-1)+f(n/2) 完整代码: /*63ms,4300KB*/ #include<cstdio> const int mod = 1e9; const int maxn

POJ 2229 Sumsets(找规律,预处理)

题目 参考了别人找的规律再理解 /* 8=1+1+1+1+1+1+1+1+1 1 8=1+1+1+1+1+1+1+2 2 3 8=1+1+1+1+2+2 8=1+1+1+1+4 4 5 8=1+1+2+2+2 8=1+1+2+4 6 7 8=2+2+2+2 8=2+2+4 8=4+4 8=8 8~9 */ /* 以下引用自博客:http://blog.csdn.net/scorpiocj/article/details/5940456 如果i为奇数,肯定有一个1,把f[i-1]的每一种情况加一个

POJ 2229 Sumsets(简单DP)

Farmer John commanded his cows to search for different sets of numbers that sum to a given number. The cows use only numbers that are an integer power of 2. Here are the possible sets of numbers that sum to 7: 1) 1+1+1+1+1+1+1 2) 1+1+1+1+1+2 3) 1+1+1