本题需要用堆来动态管理最大的偶数。
可以用优先队列或multiset实现。
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define sc(x) scanf("%lld", &(x)) int main() { ll ans = 0, n, k, a; priority_queue<ll> q; sc(n), sc(k); while (n--) { sc(a); ans += a; //先把所有的数加起来 if (a % 2 == 0) q.push(a); //所有的偶数进优先队列 } while (!q.empty() && k--) { //还有偶数而且次数没用完 ll now = (q.top() / 2); ans -= now; //执行一次操作 if (now % 2 == 0) q.push(now); q.pop(); } printf("%lld\n", ans); }
学习@19zhaoyang的multiset写法:
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define sc(x) scanf("%lld", &(x)) int main() { ll n, m, x; sc(n), sc(m); multiset<ll, greater<ll>> st; ll ans = 0; for (int i = 1; i <= n; ++i) { sc(x); if (x & 1) ans += x; //统计奇数 else st.insert(x); //加入偶数 } while (m && st.size()) { int now = *st.begin(); st.erase(st.begin()); //删除堆顶 if (now & 1) ans += now; //奇数不消耗次数,加入答案 else st.insert(now / 2), --m; } for (auto& it : st) ans += it; //相当于用const &遍历,更高效 printf("%lld\n", ans); return 0; }