1241-外卖店优先级

题目描述

关系

内容

“饱了么”外卖系统中维护着 N 家外卖店,编号 1N

每家外卖店都有一个优先级,初始时 (0 时刻) 优先级都为 0

每经过 1 个时间单位,如果外卖店没有订单,则优先级会减少 1,最低减到 0;而如果外卖店有订单,则优先级不减反加,每有一单优先级加 2

如果某家外卖店某时刻优先级大于 5,则会被系统加入优先缓存中;如果优先级小于等于 3,则会被清除出优先缓存。

给定 T 时刻以内的 M 条订单信息,请你计算 T 时刻时有多少外卖店在优先缓存中。

输入格式

第一行包含 3 个整数 N,M,T

以下 M 行每行包含两个整数 tsid,表示 ts 时刻编号 id 的外卖店收到一个订单。

输出格式

输出一个整数代表答案。

数据范围

1N,M,T105,
1tsT,
1idN

输入样例:

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

输出样例:

1

样例解释

6 时刻时,1 号店优先级降到 3,被移除出优先缓存;2 号店优先级升到 6,加入优先缓存。

所以是有 1 家店 (2 号) 在优先缓存中。

问题分析

最初思路

两种遍历方式,要么按照记录遍历,要么按照时间遍历。

肯定是按照时间遍历,因为 t 时刻可能不会有记录。关键问题是如何记录各个店铺的优先级的变化。由于一条记录只有可能增加一个店铺的优先级,并且过了一个时间段后,所有的店铺的优先级都是降低。

有点差分的意思。

思路分析

执行流程设计

总结

代码实现

#include <bits/stdc++.h>
using namespace std;

#define x first
#define y second

typedef pair<int, int> pii;

const int N = 1e5 + 10;
int n, m, T;
pii order[N];
int score[N], last[N];
bool st[N];


int main()
{
    cin >> n >> m >> T;

    for (int i = 0; i < m; i++) cin >> order[i].x >> order[i].y;
    
    sort(order, order + m);
    
    for (int i = 0; i < m;) {
        int j = i;
        while (j < m && order[i] == order[j]) j++;
        int t = order[i].x, id = order[i].y, cnt = j - i;
        i = j;
        
        score[id] -= t - last[id] - 1;
        if (score[id] < 0) score[id] = 0;
        if (score[id] <= 3) st[id] = false;
        
        score[id] += cnt * 2;
        if (score[id] > 5) st[id] = true;
        
        last[id] = t;
    }
    
    for (int i = 1; i <= n; i++) {
        if (last[i] < T) {
            score[i] -= T - last[i];
            if (score[i] <= 3) st[i] = false; 
        }
    }
    
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        if (st[i]) ans++;
    }
    cout << ans;
    return 0;
}