1. 程式人生 > 實用技巧 >AcWing 畜欄預定

AcWing 畜欄預定

方法來自書上,這題讓我想起了先前做過的一道題,都是分組問題.

按照開始吃草的時間將牛排序,使用一個小根堆,儲存每個畜欄最後一頭牛結束吃草的時間.

對於每一頭牛,嘗試將其加入到堆頂對應的畜欄,如果失敗則需要一個新的畜欄.

所以,在O(nlogn)快排之後,對於每頭牛都進行O(logn)的操作(堆的push, pop),最終複雜度是O(nlogn).這題n2已經上億了,線性掃描畜欄的方法會TLE.

此外,學習一下如何建立一個以結構體為元素的堆並對其進行操作.技巧總結在此.

#include <algorithm>
#include <cstdio>
#include 
<cstring> #include <iostream> #include <queue> using namespace std; int n, ct, ans[50010]; struct S { int begin, end, num; } t[50010]; struct node { int val, num; }; struct cmp { bool operator()(const node &a, const node &b) { return a.val > b.val; } }; priority_queue
<node, vector<node>, cmp> q; bool cmpS(S a, S b) { return a.begin < b.begin; } int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%d%d", &t[i].begin, &t[i].end); t[i].num = i; } sort(t + 1, t + n + 1, cmpS); for (int
i = 1; i <= n; i++) { bool bad = true; // for (int j = 1; j <= ct; j++) int to; if(!q.empty()) { to = q.top().num; if (t[i].begin > q.top().val) { ans[t[i].num] = to; q.pop(); q.push({t[i].end, to}); bad = false; } } if (bad) { ct++; q.push({t[i].end, ct}); ans[t[i].num] = ct; } } printf("%d\n", ct); for (int i = 1; i <= n; i++) printf("%d\n", ans[i]); return 0; }