北大OJ3977

来源:互联网 发布:sql限制返回条数 编辑:程序博客网 时间:2024/05/29 07:48
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <algorithm>#include <vector>using namespace std;const int maxint = -1u>>1;template <class T> bool get_max(T& a, const T &b) {return b > a? a = b, 1: 0;}template <class T> bool get_min(T& a, const T &b) {return b < a? a = b, 1: 0;}int l1, l2;long long data[40];struct node{    long long n;    int cnt;    bool operator < (const node &aa) const {        if (n != aa.n)            return n < aa.n;        return cnt < aa.cnt;    }}a[270000], b[270000];void dfs(int index, int cnt, long long sum, int end) {    if (index > end) {        if(cnt) {            a[++l1].n = -sum;            a[l1].cnt = cnt;        }        return;    }    dfs(index + 1, cnt, sum, end);    dfs(index + 1, cnt + 1, sum + data[index], end);}void dfs1(int index, int cnt, long long sum, int end) {    if (index > end) {        if(cnt) {            b[++l2].n = sum; b[l2].cnt = cnt;        }        return;    }    dfs1(index + 1, cnt, sum, end);    dfs1(index + 1, cnt + 1, sum + data[index], end);}long long _abs(long long n) {    return n >= 0 ? n : -n;}#define inf 0x7fffffffffffffffLLint main() {    int n, nn;    while(scanf("%d", &n), n)    {        bool flag=false;        for(int i = 1; i <= n; i++)        {            scanf("%I64d", &data[i]);            if(data[i]==0)                flag=true;        }        if(flag)        {            printf("0 1\n");            continue;        }        if (n == 1) {            printf("%I64d %d\n", _abs(data[1]), 1);            continue;                    }        l1 = l2 = 0;        nn = n/2;        dfs(1, 0, 0, nn);//左边取反,右边不取反??好查找        dfs1(nn+1, 0, 0 ,n);//咋不加1?因为nn和n都比实际长度大1        sort(a+1, a + l1+1);        int LL = 1;        for(int i =2 ;i <= l1; i++)            if(a[i].n != a[i-1].n)                a[++LL] = a[i];        l1= LL;        sort(b+1, b + l2+1);        LL = 1;        for(int i = 2; i<= l2;i++)            if( b[i].n != b[i-1].n)                b[++LL] = b[i];        l2 = LL;        ///////////////////////////////////////////        long long ans = inf;        int cnt;        long long tmp;        int i = 1;        for (int j = 1; j <= l2; j++)        {            while(i <= l1 && a[i].n < b[j].n) i++;            if (i <= l1)            {                tmp = _abs(b[j].n - a[i].n);                if (ans > tmp || (ans == tmp && cnt > b[j].cnt + a[i].cnt))                {                    ans = tmp;                    cnt = b[j].cnt + a[i].cnt;                }            }            if (i > 1)            {                tmp = _abs(b[j].n - a[i - 1].n);                if (ans > tmp || (ans == tmp && cnt > b[j].cnt + a[i - 1].cnt))                {                    ans = tmp;                    cnt = b[j].cnt + a[i - 1].cnt;                }            }        }        for(i = 1; i<= l1; i++)        {            tmp = _abs(a[i].n);            if(ans > tmp || ((ans == tmp) && cnt >a[i].cnt))            {                ans = _abs(a[i].n);                cnt = a[i].cnt;            }        }        for(i = 1; i<= l2; i++)        {            tmp = _abs(b[i].n);            if(ans > tmp || ((ans == tmp) && cnt >b[i].cnt))            {                ans = tmp;                cnt = b[i].cnt;            }        }        //printf("i = %d ans = %I64d, cnt = %d\n",i, ans ,cnt);        printf("%I64d %d\n", ans, cnt);    }    return 0;}
0 0
原创粉丝点击