CF Round#778 C - Alice and the Cake
C - Alice and the Cake
队列/优先队列
-
记录每个重量的蛋糕个数
-
求出蛋糕的重量之和,看这个重量能否切出这些蛋糕
-
把总和放入队列,如果当前这个重量还有蛋糕,那就不切这个,如果没有就继续切
但是这样广搜,很多重量其实是切不出来的,但要一直切到 1 才能判断出来,所以效率很低
因为最多切 \(n-1\) 次,所以每切一次就记录下来,切够 \(n - 1\) 次就不切了
如果用优先队列,维护一个小根堆,小重量很快就可以判断出能不能切出,这样效率也很高
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
int n;
ll a[N];
int h;
bool flag;
map<ll, ll> cnt;
int main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int T;
cin >> T;
while(T--)
{
flag = false;
cnt.clear();
cin >> n;
ll sum = 0;
h = 0;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
cnt[a[i]]++;
sum += a[i];
}
queue<ll> q;
q.push(sum);
int t = 0;
flag = true;
while(!q.empty())
{
ll c = q.front();
q.pop();
if (cnt[c] > 0)
cnt[c]--;
else
{
t++;
ll a = c / 2, b = c - a;
//cout << t << " " << a S<< " " << b << " " << cnt[a] << " " << cnt[b] << endl;
if (a >= 2)
q.push(a);
else
cnt[a]--;
if (b >= 2)
q.push(b);
else
cnt[b]--;
if (t == n)
break;
}
}
for (auto i : cnt)
{
if (i.second != 0)
{
flag = false;
//cout << i.first << " " << i.second << endl;
}
}
cout << (flag ? "YES" : "NO") << endl;
}
return 0;
}