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