Python题解—外卖店优先级
题目描述
"饱了么"外卖系统中维护着 N 家外卖店,编号 1 ∼ N。每家外卖店都有一个优先级,初始时 (0 时刻) 优先级都为 0。
每经过 1 个时间单位,如果外卖店没有订单,则优先级会减少 1,最低减到 0;而如果外卖店有订单,则优先级不减反加,每有一单优先级加 2。
如果某家外卖店某时刻优先级大于 5,则会被系统加入优先缓存中;如果 优先级小于等于 3,则会被清除出优先缓存。
给定 T 时刻以内的 M 条订单信息,请你计算 T 时刻时有多少外卖店在优先缓存中?
输入描述
第一行包含 3 个整数 N,M,T
以下 M 行每行包含两个整数 ts,id,表示 ts时刻编号 id 的外卖店收到一个订单。
其中,1$ \leq N,M,T \leq 10^5,1 \leq ts \leq T,1 \leq id \leq N$。
样例输入
2 6 6
1 1
5 2
3 1
6 2
2 1
6 2
样例输出
1
问题分析:
- 本题是一个模拟题,相对来说比较复杂。我们首先考虑题目给了什么。
- N 家外卖店,这是所有变量的基本属性,完全可以用列表的序列去存储
- 优先级。这是一个变量,初始值为0
- 时间单位。这是一个常规的变量。时间的增加表示一种过程。
- 优先缓存。这也是一个变量。不过是一个01变量
- 本题第一次使用了双层for循环,对每家店的每个时刻进行遍历,然而tle了。这个双层循环中存在许多问题导致速度变慢。
- 不需要对每个时刻进行遍历,只要将时刻按顺序排列,比较前后两个时间即可
- 优先级,时间单位,优先缓存变量全部由过程中获得。
- 思考问题的角度有待商榷。对每家店的每个时刻遍历,很多情况都是没必要的
- 解决这些问题
- 以实例去模拟,改变思考问题的角度。外卖派送是以订单为导向的,所以完全可以遍历订单,来模拟过程。
- 以空间去换时间。双层循环占用的空间是小的。因为优先级,时间单位,优先缓存变量仅仅在过程中开辟,在结束时收回。我们完全可以事先为这些变量开辟空间。
- 不必对每个时刻进行遍历。
拟定计划:
- 模拟题,按照过程给出代码
- 使用列表存储变量,节省时间
- 以订单为导向进行思考
n, m, t = map(int, input().split())
orders = []
# 输入订单
for i in range(m):
order = list(map(int, input().split()))
orders.append(order)
# 对订单按照时间进行排序,因为本题模拟按照时间顺序
orders.sort(key=lambda a : a[0])
# 为优先级,时间和标志变量开辟空间
priors = [0 for i in range(n)]
times = [0 for i in range(n)]
flags = [0 for i in range(n)]
# 对所有的订单进行遍历
for i in range(m):
time = orders[i][0]
id = orders[i][1] - 1
# 当订单的时间与上一时间不同时,优先级会在没有订单时减少
if time != times[id]:
priors[id] -= time - times[id] - 1
# 优先级最低减到0
if priors[id] < 0:
priors[id] = 0
# 优先级减少,判断是否会被清除出优先缓存
if priors[id] <= 3:
flags[id] = 0
# 接到订单,优先级加2
priors[id] += 2
# 优先级增加,判断是否会加入优先缓存中
if priors[id] > 5:
flags[id] = 1
# 时间增加后,要进行替换
times[id] = time
# 对订单后续时间段进行模拟
for i in range(n):
# 对于后续阶段,没有订单,优先级会减少1
if times[i - 1] != t:
priors[i - 1] -= t - times[i - 1]
# 优先级最低减到0
if priors[i - 1] < 0:
priors[i - 1] = 0
# 优先级减少,判断是否会被清除出优先缓存
if priors[i - 1] <= 3:
flags[i - 1] = 0
print(sum(flags))
回顾反思:
- 模拟过程,精进思考问题的角度,以此节省时间
- 空间换时间,确定变量,为变量开辟空间。

浙公网安备 33010602011771号