CF Round#778 C - Alice and the Cake
阿新 • • 發佈:2022-05-23
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; }