快轉到主要內容

CSES-1091 Concert Tickets

目錄


題目連結:https://cses.fi/problemset/task/1091

題意
#

題目給定 \( 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";
    }
}
Piau 的筆記本
作者
Piau 的筆記本
希望我寫下來的東西能夠長久的記在我的腦中