CF 1654C Alice and the Cake(模拟)

题目链接:点击跳转

题意: 爱丽丝有一块蛋糕,她要把蛋糕切成n份,每一次操作,她会选择一块蛋糕(另大小为A),将其切成两半,两块大小分别为A / 2, (A + 1) / 2,及分成整数的两半,如果原大小为奇数,则一块会大1,现在给出一个序列,问有没有可能为一块蛋糕经过n - 1次操作后得到的

思路: 由每一块拼回去会因为有不同的拼接操作无法判断,可以逆向思维,模拟一块完整的蛋糕切成现在的大小序列,通过维护两个最大堆,如果模拟的堆顶小于该序列,说明无法切出这个序列,输出NO,如果等于,说明序列中的一个元素已经得到,将两个堆顶元素都弹出,如果大于,说明还需要切的更小,将切完的结果压回堆中。

代码如下:

#include<bits/stdc++.h>
#include <ostream>

using namespace std;
typedef long long ll;
#define endl '\n'
typedef pair<int, int> PII;
#define debug() cout.flush()
#define for0(i, a) for (ll i = 0; i < a; ++i)
#define REP(i, a, b)  for (ll i = a; i < b; ++i)
#define RREP(i, a, b) for (int i = a; i >= b; --i)
const ll MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int MAXN = 2e5 + 5e2;

inline void init() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
}

inline void solve() {
    int T;
    cin >> T;
    while (T--) {
        int n;
        cin >> n;
        priority_queue<ll> q, p;
        ll tot = 0;
        for0 (i, n) {
            ll a;
            cin >> a;
            tot += a;
            q.push(a);
        }
        bool f = true;
        p.push(tot);
        while (!q.empty()) {
            ll qt = q.top();
            q.pop();
            ll pt = p.top();
            p.pop();
            if (qt != pt) {
                if (qt > pt) {
                    f = false;
                    break;
                } else {
                    q.push(qt);
                    p.push(pt >> 1);
                    p.push(pt + 1 >> 1);
                }
            }
        }
        cout << (f ? "YES" : "NO") << endl;
    }
}

signed main() {
    init();
    solve();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值