UESTC 86 Divide(贪心+二进制)

本文探讨了一种解决复杂宝物分配问题的方法,通过预处理和二进制运算,实现价值最小宝物的高效分配,确保价值差最小。详细介绍了算法步骤和实例应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://acm.uestc.edu.cn/#/problem/show/86
弱校联萌的题,比赛时没出,赛后看了题解补的。
题目大意是有多堆宝物,每堆价值为2^ai个数为xi,输出把所有宝物分成两堆价值差的最小值的二进制表示。
进行预处理,类似于二进制运算,从价值最小宝物开始进位,同时标记当前位是否被进位过,被进位过的那一位不管最后值是多少总是可以均分的。然后把最高位不能均分的宝物作为一堆,其他的比他小的作为一堆即可。

#include <cstdio>
#include <cstring>
#include <algorithm>
typedef long long LL;
using namespace std;
const int maxn = 100010;
LL a[maxn];
bool en[maxn];
int main() {
    int t, tt = 0; scanf("%d", &t);
    while (t--) {
        int n; scanf("%d", &n);
        memset(a, 0, sizeof a);
        memset(en, 0, sizeof en);
        for (int i = 1; i <= n; ++i) {
            int k, x;scanf("%d%d", &k, &x);
            a[k] += x;
        }
        printf("Case #%d: ", ++tt);
        for (int i = 0; i < maxn; ++i) {
            if (a[i] >= 2) {
                a[i+1] += a[i]/2;
                a[i] &= 1;
                en[i+1] = true;
            }
        }
        int Max = -1;
        for (int i = maxn-1; i >= 0; --i)
            if (a[i]&1 && !en[i]) {
                Max = i;
                break;
            }
        bool flag = false;
        for (int i = 0; i <= Max; ++i) {
            if (flag) a[i] ^= 1;
            else if (a[i]) flag = true;
        }
        flag = false;
        for (int i = max(0, Max); i >= 0; --i) {
            if (a[i]) flag = true;
            if (flag || i == 0) printf("%lld", a[i]);
        }
        puts("");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值