原题链接
Sumsets
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 10698 Accepted: 2919
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
题意:就是从一个数的集合中选出来4个元素满足a+b+c=d,求出最大的d,若是列举的话那么其复杂度会有n4这么多,那么肯定超时,所以我们想到可不可以列举三个数的和,但是这也是不可行的,因为10003太大了,而且不能存储,怎么办呢,将上面的方程进行变形得到a+b=d-c,所以我们可以来枚举a+b和d-c,d从大到小开始枚举,自然这样d就是最大的了,这样算下来复杂度才是n2log(n2)
//http://poj.org/problem?id=2549
#include <algorithm>
#include <iostream>
#include <utility>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <map>
#include <set>
using namespace std;
typedef long long ll;
const int MOD = int(1e9) + 7;
//int MOD = 99990001;
const int INF = 0x3f3f3f3f;
const ll INFF = (~(0ULL)>>1);
const double EPS = 1e-9;
const double OO = 1e20;
const double PI = acos(-1.0); //M_PI;
const int fx[] = {-1, 1, 0, 0};
const int fy[] = {0, 0, -1, 1};
const int maxn=1000 + 5;
//a+b+c=d;
int n;
ll a[maxn];
struct node
{
ll val;//代表a+b的值
int loc1,loc2;//代表a与b的下标
}res[maxn*maxn];//l代表的是所有的a+b的值
bool _find(int l,int r,int d,int c,ll sum){
while(r-l>1){
int mid=(l+r)/2;
if(res[mid].val>=sum) r=mid;
else l=mid;
}
if(res[r].val!=sum) return false;
else{
if(d==res[r].loc1||d==res[r].loc2||c==res[r].loc1||c==res[r].loc2) return false;
else return true;
}
}
bool cmp(node x,node y){
return x.val < y.val;
}
int main(){
while(scanf("%d",&n)==1 && n){
for(int i=0;i<n;i++)
scanf("%lld",&a[i]);
sort(a,a+n);
int len=0;
for(int i=0;i<n-1;i++){
for(int j=i+1;j<n;j++){
res[len].loc1=i;res[len].loc2=j;
res[len++].val=a[i]+a[j];
}
}
sort(res,res+len,cmp);
res[len++].val=INFF;
for(int d=n-1;d>0;d--){
for(int c=d-1;c>=0;c--){
if(_find(-1,len,d,c,a[d] - a[c])){
printf("%lld\n",a[d]);
goto END;
}
}
}
printf("no solution\n");
END:;
}
return 0;
}