試題 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);
    }
    
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM