试题 G: 外卖店优先级 第十届蓝桥杯

试题 G: 外卖店优先级
时间限制: 1.0s 内存限制: 512.0MB 本题总分: 20
【问题描述】
“饱了么”外卖系统中维护着 N 家外卖店,编号 1 N。每家外卖店都有
一个优先级,初始时 (0 时刻) 优先级都为 0
每经过 1 个时间单位,如果外卖店没有订单,则优先级会减少 1,最低减
0;而如果外卖店有订单,则优先级不减反加,每有一单优先级加 2
如果某家外卖店某时刻优先级大于 5,则会被系统加入优先缓存中;如果
优先级小于等于 3,则会被清除出优先缓存。
给定 T 时刻以内的 M 条订单信息,请你计算 T 时刻时有多少外卖店在优
先缓存中。
【输入格式】
第一行包含 3 个整数 NM 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 1000001 ts T1 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);
    }
    
}

 

posted @ 2019-04-08 10:49  一转身已万水千山  阅读(2962)  评论(2编辑  收藏  举报