蓝桥杯——外卖店优先级

外卖店优先级

题目分析

这一题一看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);
}
}
相关推荐
闻缺陷则喜何志丹6 小时前
【计算几何 二分查找】P12261 [蓝桥杯 2024 国 Java B] 激光炮|普及+
c++·数学·蓝桥杯·计算几何·洛谷
_OP_CHEN7 小时前
【算法基础篇】(三十一)动态规划之基础背包问题:从 01背包到完全背包,带你吃透背包问题的核心逻辑
算法·蓝桥杯·动态规划·背包问题·01背包·完全背包·acm/icpc
闻缺陷则喜何志丹8 小时前
【计算几何】P12144 [蓝桥杯 2025 省 A] 地雷阵|普及+
c++·数学·蓝桥杯·计算几何
迈巴赫车主11 小时前
蓝桥杯 20531黑客java
java·开发语言·数据结构·算法·职场和发展·蓝桥杯
Benmao⁢1 天前
C语言期末复习笔记
c语言·开发语言·笔记·leetcode·面试·蓝桥杯
_OP_CHEN3 天前
【算法基础篇】(二十九)路径类线性 DP 保姆级教程:从矩阵到迷宫,覆盖 4 道经典题 + 优化神技
算法·矩阵·蓝桥杯·动态规划·算法竞赛·acm/icpc·路径类动态规划
_OP_CHEN3 天前
【算法基础篇】(二十八)线性动态规划之基础 DP 超详解:从入门到实战,覆盖 4 道经典例题 + 优化技巧
算法·蓝桥杯·动态规划·运筹学·算法竞赛·acm/icpc·线性动态规划
云泽8083 天前
蓝桥杯算法精讲:前缀和与差分算法的应用与实战
算法·职场和发展·蓝桥杯
Swift社区3 天前
LeetCode 444 - 序列重建
算法·leetcode·蓝桥杯
potato_may4 天前
工程框架搭建(续)
蓝桥杯·嵌入式·硬件·国赛·调度器·裸机开发·stm2