uva 10125 - Sumsets(技巧性枚举)

题目链接http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1066

Problem C - 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
 
直接暴力的话,n4;即使查找时二分,还是n3logn
这里的技巧是,把所有a+b先存起来,再枚举c,d(不是a+b和c,那样还是n3),进行查找(a+b)是否有符合条件的即可
注意数据可以是负的,不要默认成d>c了
 
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
using namespace std;
map <int,int> M;
struct Node{
    int value,fir,sed;
};
vector <Node> V[1000000];
int cnt,num[1005];

int main(){
    int n,tag,ans;
    while(1){
        ans = -1000000000;cnt = 0;tag = 0;
        M.clear();
        for(int i = 0;i < 1000000;i++)
            V[i].clear();
        cin >> n;
        if(n == 0)  break;
        for(int i= 0 ;i < n;i++){
            cin >> num[i];
        }
        sort(num,num+n);
        for(int i= n-1;i >= 0;i--){
            for(int j = i-1;j >= 0;j--){
                int tem = num[i] + num[j];
                if(!M.count(tem)){
                    M[tem] = cnt;
                    cnt++;
                }
                int p = M[tem];
                Node sum;
                sum.value = num[i] + num[j];
                sum.fir = num[i];sum.sed = num[j];
                V[p].push_back(sum);
            }
        }
        for(int d = n-1;d >= 0;d--){
            if(tag == 1)    break;
            for(int c = n-1;c >= 0;c--){
                if(tag == 1)    break;
                if(c == d)  continue;
                int differ = num[d] - num[c];
                if(M.count(differ)){
                    int px = M[differ];
                    for(int i = 0;i < V[px].size();i++){
                        if(V[px][i].fir != num[d] && V[px][i].sed != num[d] && V[px][i].fir != num[c] && V[px][i].sed != num[c]){
                            tag = 1;
                            ans = max(ans,num[d]);
                            break;
                        }
                    }

                }
            }
        }
        if(!tag)
            cout << "no solution\n";
        else
            cout << ans << endl;
    }
    return 0;
}

你可能感兴趣的:(uva 10125 - Sumsets(技巧性枚举))