第十届蓝桥杯javaB组 G题:外面优先级(java实现)
作者:
Acccccc丶
,
2019-12-04 15:24:38
,
所有人可见
,
阅读 1006
试题 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
自己代码
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
public class Main {
static int ans;
static int n;
static int m;
static int t;
static int N = (int) (1e5 + 10);
static int[] last = new int[N]; // 记录该店的上一次订单的时间,方便下一次订单来时,减去时间间隔
static boolean[] st = new boolean[N];// 记录是否进入优先队列
static int[] score = new int[N];// 记录优先级
static ArrayList<Order> list = new ArrayList<Order>();
public static void main(String[] args) throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String[] str = reader.readLine().split(" ");
n = Integer.parseInt(str[0]);
m = Integer.parseInt(str[1]);
t = Integer.parseInt(str[2]);
for (int i = 0; i < m; i++) {
str = reader.readLine().split(" ");
int time = Integer.parseInt(str[0]);
int id = Integer.parseInt(str[1]);
list.add(new Order(time, id));
}
Collections.sort(list);
for (Order o : list) {
int time = o.time;
int id = o.id;
// 只有订单时间间隔大于1,才进行相减
if (time - last[id] > 1)
score[id] -= time - last[id] - 1;
if (score[id] < 0)
score[id] = 0;
// 小于等于3的要及时清除出优先队列,要不然会使后面会多计算
if (score[id] <= 3)
st[id] = false;
score[id] += 2;
last[id] = time;
if (score[id] > 5)
st[id] = true;
}
for (int i = 1; i <= n; i++) {
if (last[i] < t) {
score[i] -= t - last[i];
if (score[i] < 0)
score[i] = 0;
if (score[i] <= 3)
st[i] = false;
}
}
for (int i = 1; i <= n; i++) {
if (st[i])
ans++;
}
System.out.println(ans);
}
}
class Order implements Comparable<Order> {
int time;
int id;
public Order(int time, int id) {
this.time = time;
this.id = id;
}
@Override
public int compareTo(Order o) {
// TODO Auto-generated method stub
return this.time - o.time;
}
}
Y总代码
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
public class Main {
static int N=100005;
//score 数组记录每个店铺得分
static int[] score=new int[N];
//last数组 是每个店铺最后一次接收到订单的时刻
static int[] last=new int[N];
//st数组记录是否进入优先缓存区
static boolean[] st=new boolean[N];
static ArrayList<Order> list=new ArrayList<Order>();
public static void main(String[] args) {
Scanner cin=new Scanner(System.in);
int n=cin.nextInt();
int m=cin.nextInt();
int t=cin.nextInt();
for(int i=0;i<m;i++) {
int ts=cin.nextInt();
int id=cin.nextInt();
list.add(new Order(ts,id));
}
Collections.sort(list);
for(int i=0;i<m;i++) {
int j=i;
Order a =list.get(i);
int time=a.time; int id=a.id;
//记录同一时刻,相同id的店铺一共接受j个订单
while(list.get(j).time==time&&list.get(j).id==id) {
j++;
if(j==list.size()) {
break;
}
}
//优先级得分要减去 当前店铺在之前最后一次接收订单的时间和当前时刻再次接收到订单的时间差
score[id]-=time-last[id]-1;
if(score[id]<0) score[id]=0;
if(score[id]<=3) st[id]=false;
last[id]=time;
//优先级得分要加上 当前时刻 接收到的总订单数(j-i)*2
score[id]+=(j-i)*2;
if(score[id]>5) {
st[id]=true;
}
//i下次是从j的位置开始遍历,因为i到j都是同样的id和time,但是要减1,因为执行完了循环体++1
i=j-1;
}
for(int i=1;i<=n;i++) {
if(last[i]<t) {
score[i]-=t-last[i];
if(score[i]<0) score[i]=0;
if(score[i]<=3) st[i]=false;
}
}
int res=0;
for(int i=1;i<=n;i++) {
if(st[i]==true) res++;
}
System.out.println(res);
}
}
class Order implements Comparable<Order>{
int time;
int id;
public Order(int time, int id) {
super();
this.time = time;
this.id = id;
}
@Override
public int compareTo(Order o) {
// TODO Auto-generated method stub
if(this.time==o.time) {
return this.id-o.id;
}
return this.time-o.time;
}
@Override
public String toString() {
return "Order [time=" + time + ", id=" + id + "]";
}
}