藍橋杯-外賣店優先順序(簡單寫法)

小程xy發表於2024-05-15

“飽了麼”外賣系統中維護著 N 家外賣店,編號 1∼N。

每家外賣店都有一個優先順序,初始時 (0 時刻) 優先順序都為 0。

每經過 1 個時間單位,如果外賣店沒有訂單,則優先順序會減少 1,最低減到 0;而如果外賣店有訂單,則優先順序不減反加,每有一單優先順序加 2。

如果某家外賣店某時刻優先順序大於 5,則會被系統加入優先快取中;如果優先順序小於等於 3,則會被清除出優先快取。

給定 T 時刻以內的 M 條訂單資訊,請你計算 T 時刻時有多少外賣店在優先快取中。

輸入格式

第一行包含 3 個整數 N,M,T。

以下 M 行每行包含兩個整數 ts 和 id,表示 ts 時刻編號 id 的外賣店收到一個訂單。

輸出格式

輸出一個整數代表答案。

資料範圍

1≤N,M,T≤105,
1≤ts≤T,
1≤id≤N

輸入樣例:

2 6 6
1 1
5 2
3 1
6 2
2 1
6 2

輸出樣例:

1

樣例解釋

6 時刻時,1 號店優先順序降到 3,被移除出優先快取;2 號店優先順序升到 6,加入優先快取。

所以是有 1 家店 (2 號) 在優先快取中。

題解:

  1. 首先對所有訂單排個序 (這樣同一時刻同一訂單店鋪編號會挨著)
  2. 遍歷所有訂單, 每次更新下當前訂單的店鋪編號 在當前時刻之前需要扣的分, 然後加上當前時刻需要加上的分

2的操作看下圖

需要理解:

(j - i)的個數是等於編號5的個數, 然後一個訂單店鋪是5的獲得兩個積分;
(k - j - 1)的個數是時刻的個數, 也就是這個時間段沒有店鋪編號是5的訂單的個數

ac程式碼👇

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
#define x first
#define y second
typedef pair<int, int> PII;

PII p[N];   
int score[N]; // 優先順序的分數
int last[N];  // last[i] 表示id為 i 的店鋪上次有訂單的時刻是多少
int st[N];  // 是否在佇列

int main()
{
    int n, m, T; cin >> n >> m >> T;
    
    for (int i = 0; i < m; i ++) cin >> p[i].x >> p[i].y;
    sort(p, p + m);
    
    for (int i = 0; i < m;) // 遍歷所有訂單
    {
        int j = i;
        while (j < m && p[j] == p[i]) j ++;
        int t = p[i].x, id = p[i].y, cnt = j - i;   // t表示 店鋪編號為id的出現時候的時刻, cnt表示店鋪編號等於id的個數
        i = j;
        
        // t 時刻之前的
        score[id] -= t - last[id] - 1;  // last[id]表示店鋪編號為id的上次出現的時刻, 那麼這個時刻和當前出現的時刻t的差-1就是 這樣個時間之間沒出現過的次數
        if (score[id] < 0) score[id] = 0;
        if (score[id] <= 3) st[id] = false;
        
        // t 時刻的
        score[id] += cnt * 2;   // cnt表示同一時刻中店鋪編號都是id的個數 (因為我們按照時間排序和編號, 所以同一時刻同意標號會連續出現)
        if (score[id] > 5) st[id] = true;
        
        last[id] = t;   // 更新一下 編號為id的店鋪上次有訂單的時刻
    }
    
    for (int i = 1; i <= n; i ++)
        if (last[i] < T)    // 最後一段時間可能都沒有訂單, 需要單獨處理下
        {
            score[i] -= T - last[i];
            if (score[i] <= 3) st[i] = false;
        }

    int res = 0;
    for (int i = 1; i <= n; i ++) if (st[i]) res ++;
    
    cout << res << endl;
    return 0;
}

覺得寫得不錯的話, 點個贊吧~

相關文章