蓝桥杯——外卖店优先级

外卖店优先级

题目分析

这一题一看N,M,T的范围就知道不能暴力,要讨巧,怎么讨巧是重点。正常的思路是第一层for循环遍历订单(或者外卖店),第二层for循环遍历外卖店(或者订单),这样可以求出每个外卖店是不是在缓存里面,但是时间复杂度是 O ( N ∗ M ) = 1 e 10 > 1 e 8 O(N*M)=1e10>1e8 O(N∗M)=1e10>1e8,明显是不行的。

说一下讨巧的思路,订单我是必然要遍历的不然你不知道哪个外卖店有单子,那么可以不遍历外卖店吗?这就看我们如何处理订单了。订单应该是一个类,包含时间ts和外卖店id,我们优先对订单按照外卖店id排序,id相同时再按照ts排序,排序规则如下,

java 复制代码
static class message implements Comparable<message>{//存储订单信息
		int id,t;//订单的id和时间
		public message(int t, int id) {
			this.id = id;
			this.t = t;
		}
		@Override
		public int compareTo(message o) {
			if(this.id != o.id) {
				return this.id-o.id;
			}else {
				return this.t-o.t;
			}			
		}		
	}

现在可以开始遍历订单了,在遍历的时候我要记录两个值,一个是cnt用来表示当前外卖店的优先级大小,一个是flag用来表示当前外卖店是否被放在缓存里面。一个是ans表示我知道的在缓存里面的外卖店的数量。

java 复制代码
int flag = 0;//表示是否在优先级缓存中,在的flag=1,
int ans = 0;//记录答案
int cnt = 2;//表示外卖店的优先级大小

对于当前订单me[i],我要知道前一个订单me[i-1]是否和他是同一个外卖店,如果是,那么说明我此时把me[i-1].id的外卖店的单子都遍历完了,此时我要确定他是不是在缓存里面。两步确定法,一是确定flag是否等于1,二十确定从最后一个单子的时间到时间t内,是否会使他的优先级减少到小于等于3的情况。

java 复制代码
if(me[i].id!=me[i-1].id) {//如果变成下一个外卖店了,就要检查刚刚那个外卖店是不是在缓存中的
	//falg=1并且到达t时,没有小于等于3
	if(flag == 1 && (cnt - (t - me[i-1].t) > 3 )) {
		ans++;
	}
	cnt = 2;//此时是me[i].id有单子,那么cnt初始值应该是2
	flag = 0;//重置flag
}

否则的话,先求从上一个订单到当前这个订单,外卖店的优先级降低了多少,也就是经历的时间。那么这里为什么是int diff = me[i].t - me[i-1].t - 1;呢?举个例子,假设当前的时间是4,前一个的时间是2,那么中间没有订单的时间就是ts=3时,因此优先级应该降低1,那么也就是4-2-1。但是注意,如果出现了当前的时间是4,前一个的时间也是4,会出现4-4-1=-1的情况,但是实际此时应该优先级降低0,所以会有if(diff == -1) diff = 0;。那么这个if(cnt <= 3)一定要在cnt += 2;之前判断,举个例子,假设外卖店的当前优先级是4,那么diff=2,4减2等于2,此时应该被移出优先级缓存的,但是如果在判断之前我先给他加了2,那么此时2+2=4>3,他就不会移出优先级缓存,造成结果错误。

java 复制代码
else {
	int diff = me[i].t - me[i-1].t - 1;//优先级降低了多少 me[i].t=1  me[i-1].t=1
	if(diff == -1) diff =  0;
	cnt = Math.max(0, cnt - diff);//如果优先级降低到了负数,那么他就是0
	if(cnt <= 3) flag = 0;//如果小于等于3会被移出缓存
	cnt += 2;//出现了订单,优先级加2.
	if(cnt > 5) flag = 1;//如果大于5会被加入缓存
}

注意,最后一个外卖店,我没有判断它是否在缓存里面,所以for循环结束后要判断

java 复制代码
//对最后一个订单/最后一个外卖店进行判断
if(flag == 1 && (cnt - (t - me[m-1].t) > 3 )) {
	ans++;
}
System.out.println(ans);

题目代码

java 复制代码
import java.util.Arrays;
import java.util.Scanner;
public class Main{
	static class message implements Comparable<message>{//存储订单信息
		int id,t;//订单的id和时间
		public message(int t, int id) {
			this.id = id;
			this.t = t;
		}
		@Override
		public int compareTo(message o) {
			if(this.id != o.id) {
				return this.id-o.id;
			}else {
				return this.t-o.t;
			}			
		}		
	}
public static void main(String[] args) {
	Scanner scanner = new Scanner(System.in);
	int n = scanner.nextInt();
	int m = scanner.nextInt();
	int t = scanner.nextInt();
	message[] me = new message[m];
	for (int i = 0; i < me.length; i++) {
		me[i] =new message(scanner.nextInt(), scanner.nextInt());
	}
	Arrays.sort(me);
	int flag = 0;//表示是否在优先级缓存中,在的flag=1,
	int ans = 0;//记录答案
	int cnt = 2;//表示外卖店的优先级大小
	for (int i = 1; i < m; i++) {
		if(me[i].id!=me[i-1].id) {//如果变成下一个外卖店了,就要检查刚刚那个外卖店是不是在缓存中的
			//falg=1并且到达t时,没有小于等于3
			if(flag == 1 && (cnt - (t - me[i-1].t) > 3 )) {
				ans++;
			}
			cnt = 2;//此时是me[i].id有单子,那么cnt初始值应该是2
			flag = 0;//重置flag
		}else {
			int diff = me[i].t - me[i-1].t - 1;//优先级降低了多少 me[i].t=1  me[i-1].t=1
			if(diff == -1) diff =  0;
			cnt = Math.max(0, cnt - diff);
			if(cnt <= 3) flag = 0;
			cnt += 2;
			if(cnt > 5) flag = 1;
		}
	}
	//对最后一个订单/最后一个外卖店进行判断
	//讲日期模拟器的时候,whie循环结束后,也得有一个if语句,对最后一个日期进行检查
	if(flag == 1 && (cnt - (t - me[m-1].t) > 3 )) {
		ans++;
	}
	System.out.println(ans);
}
}
相关推荐
前端小超超2 天前
capacitor配置ios应用图标不同尺寸
ios·蓝桥杯·cocoa
汉克老师4 天前
第十四届蓝桥杯青少组C++选拔赛[2023.1.15]第二部分编程题(4 、移动石子)
c++·算法·蓝桥杯·蓝桥杯c++·c++蓝桥杯
旭意4 天前
C++微基础蓝桥杯之旅9.9-9.12
c++·算法·蓝桥杯
HAH-HAH5 天前
【蓝桥杯 2024 国 Java A】粉刷匠小蓝
c++·学习·数学·算法·职场和发展·蓝桥杯·组合数学
汉克老师6 天前
第十四届蓝桥杯青少组C++选拔赛[2023.1.15]第二部分编程题(2 、寻宝石)
c++·蓝桥杯·蓝桥杯c++·c++蓝桥杯·蓝桥杯选拔赛
汉克老师6 天前
第十四届蓝桥杯青少组C++选拔赛[2023.2.12]第二部分编程题(5、机甲战士)
c++·算法·蓝桥杯·01背包·蓝桥杯c++·c++蓝桥杯
Jared_devin6 天前
二叉树算法题—— [蓝桥杯 2019 省 AB] 完全二叉树的权值
数据结构·c++·算法·职场和发展·蓝桥杯
aaaweiaaaaaa8 天前
c++基础学习(学习蓝桥杯 ros2有C基础可看)
c++·学习·蓝桥杯·lambda·ros2·智能指针·c++类
汉克老师8 天前
第十四届蓝桥杯青少组C++选拔赛[2023.2.12]第二部分编程题(4、最大空白区)
c++·算法·蓝桥杯·蓝桥杯c++·c++蓝桥杯
scx2013100410 天前
P13929 [蓝桥杯 2022 省 Java B] 山 题解
c++·算法·蓝桥杯·洛谷