2021/3/29算法题打卡-外卖优先级
外卖店优先级
题目
外卖店优先级
时间限制: 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。
解析
模拟
先存下每个时刻的所有订单,然后计算出每个店铺,每个时刻的优先级,然后根据这个优先级表得到最后的结果
当最后T时刻的优先级大于5,则一定在优先缓存中,T时刻优先级小于等于3则一定不在优先缓存中,而当最后一个大于6的位置到最后T时刻之间出现了一个小于等于3的优先级,则一定不在优先缓存中,否则在优先缓存中
代码
package com.blueBrageCup.B2019;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
/**
* @auther thk
* @date 2021/3/29 - 10:44
*/
/*
public class T7外卖优先级 {
static List<Map<Integer,Integer>> list = new ArrayList<>(); //所以店铺的每个时刻的优先级
static Map<Integer,List<Integer>> map = new HashMap<>(); //每个时刻的订单数
static int N; //店铺
static int M; //订单
static int T; //总时间
//初始化
private static void init() {
for(int i=0;i<T;i++){
List<Integer> list = new ArrayList<>();
map.put(i+1,list);
}
for(int i=0;i<N;i++){
Map<Integer,Integer> map = new HashMap<>();
list.add(map);
}
}
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
String[] s = bf.readLine().split(" ");
N=Integer.parseInt(s[0]);
M=Integer.parseInt(s[1]);
T=Integer.parseInt(s[2]);
init();
//装入每个时刻的订单数据
for(int i=0;i<M;i++){
String[] s1 = bf.readLine().split(" ");
int b = Integer.parseInt(s1[0]); //时刻
int o = Integer.parseInt(s1[1]); //店铺id
List<Integer> list = map.get(b);
list.add(o);
map.put(b,list);
}
//取出每个时刻的所以订单
Set<Integer> set = map.keySet();
for(int j=1;j<=T;j++){
for(Map<Integer,Integer> map:list){
map.put(j,0);
}
}
//得到每个店铺,每个时间的优先级
for(int j:set){ //j是时刻
List<Integer> list2 = map.get(j); //list2是每个时刻的所有订单
List<Integer> index = new ArrayList<>();
for(int k=0;k<N;k++) { //每个店铺都有一个自己的下标
index.add(j - 1); //优先级在第一时刻是按照0+2,后面的时刻再而三按照前一个时刻加或减的,index就是当下要按照加减的下标
}
for(int k:list2) { //加的情况
for(int i=1;i<=N;i++){
if(k==i && j==1){ //第一个时刻按照0+2
list.get(i-1).put(j,2);
}else if(k==i) {
list.get(i - 1).put(j, list.get(i - 1).get(index.get(i-1)) + 2);
if(index.get(i-1)!=j) //按照前面的加过一次后,后面应该按照的自己本身来加了
index.set(i-1,index.get(i-1)+1);
}
}
}
for(int i=1;i<=N;i++) //减少的情况
if(!list2.contains(i)){ //不包含本店铺就减少1
if(j==1) //第一个时刻不减少
list.get(i-1).put(j,0);
else //按照前一个来减少,因为只可能减少一次,所以不用判断下标是否+1
list.get(i-1).put(j,list.get(i-1).get(j-1)==0?0:list.get(i-1).get(j-1)-1);
}
}
int count=0;
for(int i=0;i<N;i++){
Integer integer = list.get(i).get(T);
if(integer>5) { //如果最后一个都大于5则一定在优先中
count++;
continue;
}
if(integer<=3) //如果最后一个小于等于3则一定被清除出优先区
continue;
if(!list.get(i).containsValue(6)) //如果从未大于6过则一定是不在优先区的
continue;
else{ //如果最后一个大于三则可能是前面大于6后减少到的,这是仍然在优先区中
int index=0;
Set<Integer> set1 = list.get(i).keySet();
for(int j:set1){
if(list.get(i).get(j)>=6)
index=j; //找到最后一个大于6的位置
}
int flag=1;
for(int j=index;j<=T;j++){ //从最后一个大于6的时间节点,如何后面出现了某时刻小于3则最后一定不可能在优先区
if(list.get(i).get(j)<=3){
flag=0;
break;
}
}
if(flag==1)
count++;
}
}
System.out.println(count);
}
}

浙公网安备 33010602011771号