- 外卖店优先级
题目
提交记录
讨论
题解
视频讲解
“饱了么”外卖系统中维护着 N 家外卖店,编号 1∼N。
每家外卖店都有一个优先级,初始时 (0 时刻) 优先级都为 0。
每经过 1 个时间单位,如果外卖店没有订单,则优先级会减少 1,最低减到 0;而如果外卖店有订单,则优先级不减反加,每有一单优先级加 2。
如果某家外卖店某时刻优先级大于 5,则会被系统加入优先缓存中;如果优先级小于等于 3,则会被清除出优先缓存。
给定 T 时刻以内的 M 条订单信息,请你计算 T 时刻时有多少外卖店在优先缓存中。
输入格式
第一行包含 3 个整数 N,M,T。
以下 M 行每行包含两个整数 ts 和 id,表示 ts 时刻编号 id 的外卖店收到一个订单。
输出格式
输出一个整数代表答案。
数据范围
1≤N,M,T≤105,
1≤ts≤T,
1≤id≤N
输入样例:
2 6 6
1 1
5 2
3 1
6 2
2 1
6 2
输出样例:
1
样例解释
6 时刻时,1 号店优先级降到 3,被移除出优先缓存;2 号店优先级升到 6,加入优先缓存。
所以是有 1 家店 (2 号) 在优先缓存中。
package PTA;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String st[] = in.readLine().split(" ");
int N = Integer.parseInt(st[0]);
int M = Integer.parseInt(st[1]);
int T = Integer.parseInt(st[2]);
int arr[][] = new int[M][2];
int ans[]=new int[M+1];
for (int i = 0; i < M; i++) {
String tem[] = in.readLine().split(" ");
arr[i][0] = Integer.parseInt(tem[0]);
arr[i][1] = Integer.parseInt(tem[1]);
}
//arr[2]表示优先级,默认为0.
//按照时间先后顺序进行排序。
int tem []=new int[M+1];
int total=0;
Arrays.sort(arr, (a, b) -> a[0] - b[0]);
for (int i = 0; i < M; i++) {
ans[arr[i][1]] +=2;
if(ans[arr[i][1]] >5 && tem[arr[i][1]]==0){
tem[arr[i][1]]++;
}
for(int j=1;j<=M;j++){
if(j!=arr[i][1] && ans[j]>0){
ans[j]--;
}
}
for(int j=1;j<=M;j++){
if(tem[j]!=0 && ans[j] <=3){
tem[j]=0;
}
}
}
for(int i :tem){
if(i!=0){
total++;
}
}
System.out.println(total);
}
}
package PTA;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String sts[] = in.readLine().split(" ");
int N = Integer.parseInt(sts[0]);
int M = Integer.parseInt(sts[1]);
int T = Integer.parseInt(sts[2]);
int arr[][] = new int[M][2];
for (int i = 0; i < M; i++) {
String tem[] = in.readLine().split(" ");
arr[i][0] = Integer.parseInt(tem[0]);
arr[i][1] = Integer.parseInt(tem[1]);
}
//arr[2]表示优先级,默认为0.
//按照时间先后顺序进行排序。
int st []=new int[N+1];
int score[]=new int[N+1];
int last[] = new int[N+1];//上次商店来单的时间
int total=0;
Arrays.sort(arr, (a, b) -> a[0] - b[0]);
Set<Integer> set = new HashSet<>();
for (int i = 0; i < M && arr[i][0] <= T; i++) {
int time = arr[i][0];
int id = arr[i][1];
set.add(id);// 接到过订单的店
if(time - last[id] > 1)
score[id] -= (time - last[id] - 1);
if(score[id] < 0) score[id] = 0;
if(score[id] <= 3) st[id] = 0; // 要先置为false 否则如果先降到了3再加上2
// 虽然大于3,但不大于5
score[id] += 2;
if(score[id] > 5) st[id] = 1;
last[id] = time; // 记录某家店的最后接单时刻。
//out.write(score[id] + "\n");
}
int num = 0;
for(int i : set){
//out.write("s: " + score[i] + " last: "+ last[i] + " T: "+ T + "\n");
if(last[i] < T)
score[i] -= (T - last[i]);
if(score[i] <= 3)
st[i] = 0;
if(st[i] == 1) num ++;
}
System.out.println(num);
}
}
最后通过得,要注意初始化数组得时候是以N为标准,N表示商店的个数。
同时,在对商店进行减分的时候,如果减到为负数的话, 就要将起置为0。
package PTA;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String st[] = in.readLine().split(" ");
int N = Integer.parseInt(st[0]);
int M = Integer.parseInt(st[1]);
int T = Integer.parseInt(st[2]);
int arr[][] = new int[M][2];
for (int i = 0; i < M; i++) {
String tem[] = in.readLine().split(" ");
arr[i][0] = Integer.parseInt(tem[0]);
arr[i][1] = Integer.parseInt(tem[1]);
}
//arr[2]表示优先级,默认为0.
//按照时间先后顺序进行排序。
int tem []=new int[N+1];
int ans[]=new int[N+1];
int previous[] = new int[N+1];//上次商店来单的时间
int total=0;
Arrays.sort(arr, (a, b) -> a[0] - b[0]);
// for(int i =0;i<M;i++){
// System.out.println(arr[i][0]+" "+arr[i][1]);
// }
// System.out.println("------------------------------------");
Set<Integer> set = new HashSet<>();
for (int i = 0; i < M && arr[i][0] <= T; i++) {
int time = arr[i][0];
int id = arr[i][1];
set.add(id);
//上次来单时间大于0,即为已经来过单
//先判断之前减后得结果,再进行+2
if(time - previous[id] > 1){
ans[id] = ans[id] - (time-previous[id] -1);
}
if(ans[id] <0){
ans[id]=0;
}
if(tem[id]==1 && ans[id]<=3){
tem[id]=0;
}
ans[id] +=2;
if(ans[id] >5 && tem[id]==0){
//(arr[i][0]-previous[arr[i][1]] -1)当其差值大于1得时候才会进行减,如果是2秒1店进,3秒也是1店进,就不用减1.
tem[id]=1;
}
previous[id]=time;//改变上次来单时间
// System.out.println(id+" ss "+ans[id]);
}
for(int i:set){
//System.out.println(i+" ss ");
if(ans[i] - (T-previous[i] ) > 3 && tem[i] ==1){
total++;
//System.out.println(i+" id");
}
}
System.out.println(total);
}
}
注释更完善的:
package PTA;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String st[] = in.readLine().split(" ");
int N = Integer.parseInt(st[0]);
int M = Integer.parseInt(st[1]);
int T = Integer.parseInt(st[2]);
int arr[][] = new int[M][2];
for(int i =0;i<M;i++){
String string[] = in.readLine().split(" ");
arr[i][0]=Integer.parseInt(string[0]);
arr[i][1]=Integer.parseInt(string[1]);
}
Arrays.sort(arr,(a,b) -> a[0] - b[0]);
int tem[] = new int[N+1];//表示已经进入到优先队列的
int ans[]= new int[N+1];//表示当前分数
int pre[] = new int[N+1];
Set<Integer> set = new HashSet<>();
for(int i=0;i<M && arr[i][0]<=T;i++){
int time = arr[i][0];//当前时间
int id = arr[i][1];
set.add(id);
if(time - pre[id]>1){
//如果等于1,证明上一个也是该店,就不用减
ans[id] -= (time - pre[id] -1);
}
if(ans[id] <0){
ans[id] = 0;
}
if(tem[id]==1 && ans[id]<=3){
tem[id] =0;
}
ans[id] +=2;
if(ans[id]>5 && tem[id]==0){
tem[id]=1;
}
pre[id]=time ;//更新上次来单时间
}
int total=0;
//对所有的进行判断
for(int i: set){
if(ans[i]- (T-pre[i])>3 && tem[i]==1){
//这里不减一
total++;
}
}
System.out.println(total);
}
}