Sumsets
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
Output for Sample Input
12 no solution
解决方案:题目意思就不用讲了。直接枚举的话肯定不行的,a+b+c=d,可以将其分成两半,a+b,d-c。先枚举a+b,存至哈希表,再枚举d、c,看两边是否相等,而推出d。
代码:
#include<iostream>
#include<map>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAXN = 10000003;
const int MAXSIZE = 1030;
int n;
int rear;
struct node
{
int i, j;
int sum;
}st[MAXSIZE*MAXSIZE];
int first[MAXN], next[MAXSIZE*MAXSIZE];
int A[MAXSIZE];
int Hash(int s){
int h=s&0x7fffffff;
return h%MAXN;
}///对sum进行哈希编码,
void init()
{
rear = 0;
memset(first, -1, sizeof(first));
}
int Find(int i, int j, int s)
{
int h = Hash(s);
for(int v = first[h]; v != -1; v = next[v])
{
if(s == st[v].sum && st[v].i != i && st[v].i != j && st[v].j != i && st[v].j != j) return 1;
}
return 0;
}///寻找符合条件的A[i]-A[j];
void Insert(int s)
{
int h = Hash(st[s].sum);
next[s] = first[h];
first[h] = s;
}///形成一个并查集,以便储存形成一个sum的多个i,j;
int main(){
while(~scanf("%d",&n)&&n){
memset(next,0,sizeof(next));
for(int i=0;i<n;i++){
scanf("%d",&A[i]);
}
init();
sort(A,A+n);///对它进行排序,以便对A[i]-A[j]的组合可从A[i]的最大数开始查询
for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++){
st[rear].sum=A[i]+A[j];
st[rear].i=i;st[rear].j=j;
Insert(rear);
rear++;
}
bool flag=true;
for(int i=n-1;i>=0;i--){
for(int j=0;j<n;j++)if(i!=j){
if(Find(i,j,A[i]-A[j]))///由于前面对A[]进行的排序,所以查到的第一个符合的就是最大的那个
{printf("%d\n",A[i]);flag=false;break;}
}
if(!flag) break;
}
if(flag)
printf("no solution\n");
}
return 0;}