您的位置:首页 > 其它

10125 - Sumsets(折半枚举+二分)

2015-09-15 16:01 387 查看
该题和挑战上一道题很类似,如果枚举四个值的话,复杂度太高。 那么我们可以想办法将复杂度分开。

方法是: 先用O(n^2)预处理出来a+b,然后枚举c和d,二分查找ab中有没有恰好等于d - c的值。

细节参见代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF = 1000000000;
const int maxn = 2000+5;
int n,m,a[maxn];
struct node{
    int a,b,ab;
    bool operator < (const node& rhs) const {
        return ab < rhs.ab;
    }
}ab[maxn*maxn];
int lower(node* A,int x,int y,int v) {
    int m ;
    while(x < y) {
        m = x + (y - x)/2;
        if(A[m].ab >= v) y = m;
        else x = m + 1;
    }
    return x;
}
int main() {
    while(~scanf("%d",&n)&&n) {
        int cnt = 0;
        for(int i=0;i<n;i++) scanf("%d",&a[i]);
        sort(a,a+n);
        for(int i=0;i<n;i++) {
            for(int j=i+1;j<n;j++) {
                ab[cnt].ab = a[i]+a[j];
                ab[cnt].a = a[i]; ab[cnt++].b = a[j];
            }
        }
        sort(ab,ab+cnt);
        int ans = -1;
        for(int i=0;i<n;i++) {
            for(int j=0;j<i;j++) {
                if(ans >= a[i]) break;
                int v = a[i] - a[j];
                int u = lower(ab,0,cnt-1,v);
                if(ab[u].ab == v && ab[u].a != a[i] && ab[u].b != a[i] && ab[u].a != a[j] && ab[u].b != a[j]) ans = a[i];
            }
        }
        if(ans != -1) printf("%d\n",ans);
        else printf("no solution\n");
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: