蓝桥杯国赛每日一题:外卖店优先级(模拟)

题目描述:

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

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

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

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

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

输入格式

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

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

输出格式

输出一个整数代表答案。

数据范围

1≤N,M,T≤10^5,
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.按时间顺序先后处理每一批相同编号的订单,统计与当前编号上次

### 蓝桥杯 外卖优先级 Java 实现 解题思路 #### 1. 题目分析 题目描述了一种动态变化的优先级机制,其中每家外卖优先级随时间和订单数量的变化而调整。具体规则如下: - 如果某外卖在某一时间单位内无订单,则其优先级减少 1,但不会低于 0[^1]。 - 若该外卖在此时间内有订单,则优先级增加 2,对于每一单均如此处理[^2]。 因此,解题的核心在于如何高效地计算各外卖在指定时间 `t` 的最终优先级,同时避免因数据规模较大而导致的时间或空间复杂度过高问题[^3]。 --- #### 2. 数据结构设计 为了满足性能需求并简化逻辑,可以采用以下两种主要的数据结构: ##### (1) 哈希表 (`HashMap`) 哈希表用于存储每个时间节点上发生订单的外卖集合。键表示某个特定时间点 `t`,值是一个列表,保存在该时间点下单的所有外卖编号[^4]。 ```java Map<Integer, List<Integer>> orderMap = new HashMap<>(); ``` ##### (2) 数组 定义一个长度为 `N` 的整型数组,用来记录每一家外卖的当前优先级状态。初始化时,所有外卖优先级均为 0。 ```java int[] priorityArray = new int[N]; Arrays.fill(priorityArray, 0); ``` --- #### 3. 算法流程 以下是基于上述数据结构的具体实现步骤: ##### (1) 输入解析 读取输入数据,构建 `orderMap` 表示各个时间段内的订单情况。假设输入格式为多行数据,每行为三个整数:`time`, `store_id`, 和 `orders_count`,分别对应时间、外卖编号以及此时间下的订单量。 ```java for (int i = 0; i < M; i++) { String[] line = br.readLine().split(" "); int time = Integer.parseInt(line[0]); int storeId = Integer.parseInt(line[1]); if (!orderMap.containsKey(time)) { orderMap.put(time, new ArrayList<>()); } orderMap.get(time).add(storeId); } ``` ##### (2) 动态更新优先级 遍历从 `0` 到目标时间 `T` 的每一个时间点,在每次迭代中完成两部分操作: - **降低未接单铺的优先级**:检查哪些铺在过去一段时间里没有任何新订单,并对其执行 `-1` 操作; - **提升已接单铺的优先级**:依据当前时间点上的订单信息,对相应铺实施 `+2 * orders_count` 更新。 注意优化效率,仅针对实际存在活动的时间节点进行详细运算即可。 ```java Set<Integer> activeStores = new HashSet<>(); // 初始化活跃铺为空集 activeStores.clear(); for (int currentTime = 0; currentTime <= T; currentTime++) { // 对于非活跃铺降权 for (int s = 1; s <= N; s++) { if (!activeStores.contains(s)) { priorityArray[s - 1] = Math.max(0, priorityArray[s - 1] - 1); } else { activeStores.remove(s); // 清除标记以便下一轮重新评估 } } // 当前时刻若有新增订单则提权 if (orderMap.containsKey(currentTime)) { List<Integer> storesWithOrders = orderMap.get(currentTime); for (Integer store : storesWithOrders) { priorityArray[store - 1] += 2; activeStores.add(store); // 添加至活跃铺集合以防重复扣分 } } } ``` --- #### 4. 输出结果 最后打印出所有外卖在给定结束时间后的最终优先级数值。 ```java StringBuilder sb = new StringBuilder(); for (int p : priorityArray) { sb.append(p).append("\n"); } System.out.print(sb.toString()); ``` --- ### 总结 以上方法利用了高效的哈希映射和简单的线性扫描技术来解决大规模数据场景中的动态优先级管理问题。它不仅能够有效控制运行时间成本,还兼顾了内存使用的合理性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cocobol0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值