題意#
題目給定 \( n \) 張演唱會門票及各自價格。
接著有 \( m \) 個依序到來的顧客,每位顧客有願意支付的最高價格(預算)。
我們的任務是:為每位顧客找出剩下門票中,不超過其預算的最高價門票。
如果無法買到任何票,則該顧客空手而歸。
我們需要求出每個顧客最終購買的票價(若無則輸出 -1)。
思路#
我們需要為每位顧客尋找「小於等於預算」的最大值,且售出後門票即消失。
這需要一個能保持排序,且支援快速存取的資料結構。
在 C++ 中,可以使用 std::multiset(因票價可能重複,不適用 set)。
實作上,對於每位顧客可利用 upper_bound 找出「嚴格大於」其預算的第一張票。
該元素的前一個元素,即為不超過其預算的最高價門票。
將票售出並輸出價格後,將其從容器中刪除。
若 upper_bound 的結果為容器開頭(begin),代表沒有符合預算的門票,輸出 -1。
程式碼#
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define INF LONG_LONG_MAX/1000
#define WA() cin.tie(0)->sync_with_stdio(0)
#define all(x) (x).begin(), (x).end()
#define int long long
#define PII pair<int, int>
signed main() { WA();
int n, m; cin >> n >> m;
int x;
// 使用 multiset 儲存門票價格,自動排序並支援快速查找與刪除
multiset<int> a; while (n--) {
cin >> x; a.insert(x);
}
while (m--) {
cin >> x;
// 找出第一張嚴格大於顧客預算的門票
if (auto it = a.upper_bound(x); it != a.begin())
// 若 iterator 不是指向開頭,代表前面有符合預算的票,輸出並將其刪除
cout << *prev(it) << '\n', a.erase(prev(it));
// 若指向開頭,代表沒有符合預算的票
else
cout << "-1\n";
}
}
