试题 G: 外卖店优先级 第十届蓝桥杯
试题 G: 外卖店优先级
时间限制: 1.0s 内存限制: 512.0MB 本题总分: 20 分
【问题描述】
“饱了么”外卖系统中维护着 N 家外卖店,编号 1 ∼ N。每家外卖店都有
一个优先级,初始时 (0 时刻) 优先级都为 0。
每经过 1 个时间单位,如果外卖店没有订单,则优先级会减少 1,最低减
到 0;而如果外卖店有订单,则优先级不减反加,每有一单优先级加 2。
如果某家外卖店某时刻优先级大于 5,则会被系统加入优先缓存中;如果
优先级小于等于 3,则会被清除出优先缓存。
给定 T 时刻以内的 M 条订单信息,请你计算 T 时刻时有多少外卖店在优
先缓存中。
【输入格式】
第一行包含 3 个整数 N、 M 和 T。
以下 M 行每行包含两个整数 ts 和 id,表示 ts 时刻编号 id 的外卖店收到
一个订单。
【输出格式】
输出一个整数代表答案。
【样例输入】
2 6 6
1 1
5 2
3 1
6 2
2 1
6 2
【样例输出】
1
【样例解释】
6 时刻时, 1 号店优先级降到 3,被移除出优先缓存; 2 号店优先级升到 6,
加入优先缓存。所以是有 1 家店 (2 号) 在优先缓存中。
【评测用例规模与约定】
对于 80% 的评测用例, 1 ≤ N; M; T ≤ 10000。
对于所有评测用例, 1 ≤ N; M; T ≤ 100000, 1 ≤ ts ≤ T, 1 ≤ id ≤ N。
一个容易忽略的地方,一个在缓存队列中的店铺只有在其优先级<=3时才会被移除缓存队列,而不是优先级<=5就会被移出缓存队列。
更为方便的是用集合 List array[]=new ArrayList[T+1] 存放每个时刻拥有订单的店铺,比如array[1].add了1 2 3 4,则表示时刻1店铺1/2/3/4接受到了订单;用此方法存放好了数据以后,可以枚举每个时刻,嵌套枚举每个店铺;比如时刻array[2]时,枚举每个店铺i(i=1……N),判断每个店铺是否存在订单可以使用集合自带方法,contains(Object o),这就是使用集合而不是使用数组的好处,使用数组需要枚举每个订单号,枚举完订单号还需要将不存在订单的店铺优先级降低;而使用集合枚举每个店铺即可,存在订单则增加店铺优先级,不存在则降低,需要注意的是某个时刻一个店铺可能存在多个订单,这就需要使用集合ArrayList而不能使用集合Set(不允许存放重复元素),如何知道一个店铺在某个时刻存在多少个订单?可以使用集合方法remove(Object o),此方法可以移除集合队列中遇到的第一个元素o而不是移除全部的元素o,这就刚好符合我们的需求,当判断contains(Object o)为trye时增加相应店铺的优先级然后将其从队列中remove,再循环contains判断即可。
import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner reader=new Scanner(System.in); int res=0; //统计结果 int N=reader.nextInt(); int M=reader.nextInt(); int T=reader.nextInt(); int level[]=new int[N+1]; //存放优先级 boolean judge[]=new boolean[N+1]; //存放是否在缓存队列,初始值为false List array[]=new ArrayList[T+1]; //存放每个时刻对应的店铺 for(int i=0;i<=T;i++){ array[i]=new ArrayList(); } for(int i=1;i<=M;i++){ int ts=reader.nextInt(); int id=reader.nextInt(); array[ts].add(id); } for(int i=1;i<=T;i++){ //枚举array for(int j=1;j<=N;j++){ //枚举店铺 int flag=0; Object k=j; while(array[i].contains(k)){ //使用while是因为存在一个时刻一个店铺存在多个订单 flag=1; array[i].remove(k); level[j]+=2; if(level[j]>5){ judge[j]=true; res++; } } if(flag==0){ //此时刻无店铺j的订单 level[j]=level[j]==0?0:level[j]-1; if(judge[j]){ //原来在缓存队列 if(level[j]<=3){ //优先级下降 judge[j]=false; res--; } } } } } System.out.println(res); } }