1241-外卖店优先级
题目描述
关系
内容
“饱了么”外卖系统中维护着
每家外卖店都有一个优先级,初始时 (
每经过
如果某家外卖店某时刻优先级大于
给定
输入格式
第一行包含
以下
输出格式
输出一个整数代表答案。
数据范围
输入样例:
2 6 6
1 1
5 2
3 1
6 2
2 1
6 2
输出样例:
1
样例解释
所以是有
问题分析
最初思路
两种遍历方式,要么按照记录遍历,要么按照时间遍历。
肯定是按照时间遍历,因为 t 时刻可能不会有记录。关键问题是如何记录各个店铺的优先级的变化。由于一条记录只有可能增加一个店铺的优先级,并且过了一个时间段后,所有的店铺的优先级都是降低。
有点差分的意思。
思路分析
- 读入订单,并对订单按照时间为第一维,id 为第二维进行排序。
- 对于每个订单 order,我们都要进行如下操作:
- 找到所有相同的订单(时间与 id 都相同),统计数量为 cnt;
- 下一次遍历的位置为该订单后一个位置;
- 计算优先级 score:
- 得到上一次相同 id 的订单出现的位置 last,计算出该订单在没有出现的时间内,优先级降低了多少;
- 如果优先级小于等于 3,那么就剔除出优先缓存中;处理 t 时刻之前的信息
- 计算 t 时刻的优先级变化,如果有 cnt 个相同订单,那么优先级将会增加
cnt*2; - 如果优先级大于等于 5,那么就加入优先缓存中;
- 更新 last 为当前订单;
- 遍历所有的订单,如果发现该订单最后出现的位置不是 t 时刻(小于 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;
}