快轉到主要內容

CSES-1084 Apartments

目錄


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

題意
#

題目給定 \( n \) 個申請人與 \( m \) 間空公寓。
每個申請人有理想的公寓大小,並接受大小差距在 \( k \) 以內的房屋(即介於理想大小 \( -k \) 到 \( +k \) 之間)。
我們需要求出最多能滿足幾位申請人。

思路
#

為了讓盡可能多的人配對成功,我們可以將「申請人的預期大小」和「公寓的實際大小」分別從小到大排序。

排序後,利用雙指標(Two Pointers)來進行配對:一個指標指向申請人,另一個指向公寓。

  • 如果目前公寓小於申請人的底線,代表這間公寓無法滿足後續的申請人,直接換下一間公寓。
  • 如果公寓大於申請人的接受上限,代表此申請人無法接受後面的公寓,換下一位申請人。
  • 如果公寓大小落在申請人的接受範圍內,則成功配對,兩個指標同時前進,並將配對數加一。

這種貪婪策略能確保我們從需求小的物件開始配對,逐步滿足申請人,避免浪費配對機會。

程式碼
#

#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, k; cin >> n >> m >> k;
    deque<int> a(n), b(m);
    for (auto &i : a) cin >> i;
    for (auto &i : b) cin >> i;
    
    // 將申請人要求與公寓大小各自從小到大排序
    sort(all(a)); sort(all(b));
    
    int cnt = 0;
    // 使用雙指標同時遍歷申請人 (adx) 與公寓 (bdx)
    for (int adx = 0, bdx = 0; adx < n && bdx < m;) {
        // 如果當前公寓加上寬容度後還是小於申請人的理想值,代表公寓太小,換下一間
        if (b[bdx]+k < a[adx]) bdx++;
        // 如果公寓減去寬容度後還是大於理想值,代表公寓太大,換下一個要求較高的申請人
        else if (b[bdx]-k > a[adx]) adx++;
        // 成功落在接受範圍內,將兩人配對,指標同時前進
        else adx++, bdx++, cnt++;
    }
    
    // 輸出最多能成功配對的數量
    cout << cnt << '\n';
}
Piau 的筆記本
作者
Piau 的筆記本
希望我寫下來的東西能夠長久的記在我的腦中