http://acm.uestc.edu.cn/#/problem/show/86
弱校联萌的题,比赛时没出,赛后看了题解补的。
题目大意是有多堆宝物,每堆价值为2^ai个数为xi,输出把所有宝物分成两堆价值差的最小值的二进制表示。
进行预处理,类似于二进制运算,从价值最小宝物开始进位,同时标记当前位是否被进位过,被进位过的那一位不管最后值是多少总是可以均分的。然后把最高位不能均分的宝物 作为一堆,其他的比他小的作为一堆即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| #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; }
|
** 本文迁移自我的CSDN博客,格式可能有所偏差。 **