华为OD机试之打印机队列(Java源码)

news2024/12/26 0:26:23

打印机队列

题目描述

有5台打印机打印文件,每台打印机有自己的待打印队列。
因为打印的文件内容有轻重缓急之分,所以队列中的文件有1~10不同的代先级,其中
数字越大优先级越高
打印机会从自己的待打印队列中选择优先级最高的文件来打印。
如果存在两个优先级一样的文件,则选择最早进入队列的那个文件。
现在请你来模拟这5台打印机的打印过程。

输入描述

每个输入包含1个测试用例,

每个测试用例第一行给出发生事件的数量N(0 < N < 1000)。

接下来有 N 行,分别表示发生的事件。共有如下两种事件:

  1. “IN P NUM”,表示有一个拥有优先级 NUM 的文件放到了打印机 P 的待打印队列中。(0< P <= 5, 0 < NUM <= 10);
  2. “OUT P”,表示打印机 P 进行了一次文件打印,同时该文件从待打印队列中取出。(0 < P <= 5)。

输出描述

  • 对于每个测试用例,每次”OUT P”事件,请在一行中输出文件的编号
  • 如果此时没有文件可以打印,请输出”NULL“。
  • 文件的编号定义为”IN P NUM”事件发生第 x 次,此处待打印文件的编号为x。编号从1开始。

用例

输入7
IN 1 1
IN 1 2
IN 1 3
IN 2 1
OUT 1
OUT 2
OUT 2
输出3
4
NULL
说明
输入5
IN 1 1
IN 1 3
IN 1 1
IN 1 3
OUT 1
输出2
说明

源码和解析
解析:

1.可以使用有序列表对该题进行求解,但是这种每次添加任务队列都需要解决排序的问题,可以考虑在打印任务时再看是否有序,若无序,则可以排队,若有序,则直接输出首个任务,且直接移出这个任务。
2.另外一种方式就是使用大根堆去解决这个问题

示例代码方式一:

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class T35 {
	static class Task {
		int num;
		int priority;
		int taskId;

		public Task(int num, int priority, boolean isFinished,
				int taskId) {
			super();

			this.num = num;
			this.priority = priority;
			this.taskId = taskId;
		}

		@Override
		public String toString() {
			return "Task [num=" + num + ", priority=" + priority
					+ ", taskId=" + taskId + "]\n";
		}
	}

	// 按输入的设备编号进行分堆 存放在不同的map中 键是打印机编号 值为该打印机的任务信息
	static Map<Integer, List<Task>> taskMap = new HashMap<Integer, List<Task>>();
	static List<Integer> pList = new ArrayList<>();// 记录设备的id集
													// 后面就不用keyset去遍历map了
	static boolean isOrdered = false;

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int num = scanner.nextInt();
		int id = 0;
		for (int i = 0; i < num; i++) {
			id++;
			String op = scanner.next();
			int p = scanner.nextInt();
			int priority = 0;
			if (op.equals("IN")) {
				priority = scanner.nextInt();
			}
			if (!taskMap.containsKey(p)) {
				List<Task> tasks = new ArrayList<T35.Task>();
				taskMap.put(p, tasks);
				pList.add(p);
			}
			Task task = new Task(p, priority, false, id);
			if (op.equals("IN")) {
				taskMap.get(p).add(task);
				isOrdered = false;
			} else {
				if (!isOrdered)
					sort();
				List<Task> tasksItem = taskMap.get(p);
				Task t = tasksItem.size() == 0 ? null : tasksItem.get(0);
				if (t != null) {
					tasksItem.remove(0);
				}
				System.out.println((t == null ? "NULL" : t.taskId));
			}
		}
	}

	// 排序
	public static void sort() {
		isOrdered = true;
		for (int p : pList) {
			taskMap.get(p).sort(new Comparator<Task>() {
				@Override
				public int compare(Task o1, Task o2) {
					// 优先级降序 高的排前面 方便取值
					if (o1.priority > o2.priority) {
						return -1;
					} else if (o1.priority < o2.priority) {
						return 1;
					}
					// 优先级一样 任务顺序排序
					if (o1.taskId < o2.taskId) {
						return -1;
					} else if (o1.taskId > o2.taskId) {
						return 1;
					}
					return 0;
				}
			});
		}
	}
}

执行示意图如下:
在这里插入图片描述
在这里插入图片描述
大根堆解法
解析

例如输入
10
IN 1 2
IN 1 1
IN 1 4
IN 1 2
IN 1 4
IN 1 3
IN 1 5
OUT 1
OUT 2
OUT 2
形成的节点信息如下
在这里插入图片描述
那么在移出时就
OUT 1 针对 1 5 这个节点
OUT 1 查找到 1 5这个节点 无比他大 比他小的 那么只能是1 5 节点的父节点 1 4
OUT 1 查找到 1 4 节点是已完成的 那么可能就是1 3 节点 若1 3节点已完成 则可能是1 2 节点 若 1 2 节点已完成 则可能是其左节点1 1 若 1 1节点已完成 则看其左节点 若 1 1 节点未完成 则看其左节点
注意:这里并非是完全排序好的大根堆,而是依据节点的添加顺序形成的堆

源码示例 大根堆

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class T35 {
	static class Task {
		int devId; // 设备编号
		int priority;
		int taskId;
		boolean isFinished;
		Task leftTask; // 左节点
		Task rightTask; // 右节点
		Task parenTask;// 父节点

		@Override
		public String toString() {
			return "Task [devId=" + devId + ", priority=" + priority
					+ ", taskId=" + taskId + "]\n";
		}
	}

	// 按输入的设备编号进行分堆 存放在不同的map中 键是打印机编号 值为该打印机的任务信息
	static Map<Integer, Task> taskMap = new HashMap<Integer, Task>();
	static Task objTask = null;

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int num = scanner.nextInt();
		int id = 0;
		for (int i = 0; i < num; i++) {
			id++;
			String op = scanner.next();
			int devId = scanner.nextInt();
			int priority = 0;
			if (op.equals("IN")) {
				priority = scanner.nextInt();
			}
			Task task = new Task();
			task.devId = devId;
			task.priority = priority;
			task.taskId = id;
			if (op.equals("IN")) {
				if (!taskMap.containsKey(devId)) {
					taskMap.put(devId, task);
					System.out.println("挂载跟节点:" + task.taskId);
				} else {
					// 挂载节点
					handle(devId, task);
				}
			} else {
				// 出节点
				objTask = null;
				find(taskMap.get(devId));
				if (objTask == null)
					System.out.println("NULL");
			}
		}
	}

	// 找到目标设备要出的那个
	public static void find(Task task) {
		if (task.isFinished == false) {
			// 自己未完成 那么可能到右侧
			if (task.rightTask != null && task.rightTask.isFinished == false) {
				find(task.rightTask);// 找右侧子节点 这种是不可能找左侧子节点的
			} else {
				// 到自己
				task.isFinished = true;
				objTask = task;
				System.out.println(task.taskId);// 输出任务id
			}
		} else {
			// 当前已完成 那么只有可能是其左侧节点
			if (task.leftTask != null)
				find(task.leftTask);
		}
	}

	public static void handle(int devId, Task task) {
		Task rootTask = taskMap.get(devId);
		mount(rootTask, task);
	}

	// 遍历节点 进行挂载
	public static void mount(Task task, Task objTask) {
		if (task.priority < objTask.priority) {
			// 挂载右侧
			if (task.rightTask != null) {
				mount(task.rightTask, objTask);
			} else {
				task.rightTask = objTask;
				System.out.println("节点" + objTask.taskId + "挂载在节点"
						+ task.taskId + "右侧");
			}
		} else {
			// 挂载左侧
			if (task.leftTask != null) {
				mount(task.leftTask, objTask);
			} else {
				task.leftTask = objTask;
				System.out.println("节点" + objTask.taskId + "挂载节点" + task.taskId
						+ "左侧");
			}
		}
	}
}

大根堆代码运行示意图:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/585087.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

5月29号软件资讯更新合集......

Paozhu C Admin 管理后台 1.4.0 版本发布 Paozhu C web 框架 1.4.0 版本发布。 提供一个完整的 admin 管理后台&#xff0c;支持图片管理&#xff0c;文件上传&#xff0c;修改百度开源编辑器 ueditor 上传管理程序为 c 框架自带 C ORM 框架&#xff0c;支持 HTTP/1 HTTP/2 …

InsCode AI 创作助手使用方法

CSDN最近推出了InsCode&#xff0c;可实现对话式AI辅助编程&#xff0c;能够帮助我们高效地创作文章&#xff0c;成倍提高生产力&#xff01;让我们一起来看看如何使用吧&#xff01; 首先&#xff0c;点击进入【发布】页面 右上角显示【创作助手】&#xff0c;可直接点击进入…

Tcl-10. 字符串比较,匹配,替换,类别,映射,string 相关

一、字符串比较&#xff1a;string compare, string equal 我们在 expr 和控制语句如 if、while 中可用比较运算符””、”!” 、“”、 “”等来进行字符串比较&#xff0c;但是如不注意的话就会产生问题。首先必须用双引号来将字符串值括起来&#xff0c;这样表达式语法分析…

​​​​Linux Shell 实现一键部署Oracle21 rpm包方式

oracle前言 Oracle开发的关系数据库产品因性能卓越而闻名&#xff0c;Oracle数据库产品为财富排行榜上的前1000家公司所采用&#xff0c;许多大型网站也选用了Oracle系统&#xff0c;是世界最好的数据库产品。此外&#xff0c;Oracle公司还开发其他应用程序和软件。同时&#…

【CTF】2023Ciscn WEB方向题解

前言 太菜了太菜了&#xff0c;太久没打比赛啥也不会做&#xff0c;部分题目可去NSSCTF进行复现:NSSCTF 比赛体验一般&#xff0c;一黑灯基本上题都烂掉 unzip 这道题估计大家都会&#xff0c;算是一道原题了 参考:https://xz.aliyun.com/t/10533 由于环境没了&#xff0c;靠…

基于复旦微FMQL45T900 全国产ARM+FPGA核心板方案

XM745D 是一款基于上海复旦微电子 FMQL45T900 的全国产化 ARM 核心板。该核心板将复旦微的 FMQL45T900&#xff08;与 XILINX 的 XC7Z045-2FFG900I 兼容&#xff09;的最小系统集成在了一个 87*117mm 的 核心板上&#xff0c;可以作为一个核心模块&#xff0c;进行功能性扩展&a…

《QDebug 2023年5月》

一、Qt Widgets 问题交流 1.在 VS 中双击打开 ui 文件后&#xff0c;过一会儿 Qt Designer 就闪退 我是在 Windows11 VS2019/2022 环境遇到这个问题&#xff0c;解决方法是设置 Run in detached window 为 True。 点击 "扩展->QT VS Tools->Options"&#…

通俗易懂理解到底什么是DevOps技术(Windows程序员视角)

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天我们来聊聊到底什么是DevOps。 相信很多小伙伴为什么搞懂DevOps&#xff0c;已经不知道查了多少论坛的帖子和资料了&#xff0c;但还是很困惑的话&#xff0c;那不妨来看看我这个帖子。希望能有助于你的…

CASA模型NPP及碳源、碳汇模拟

CASA模型 CASA模型是一个基于过程的遥感模型(Potteret al&#xff0c;1993&#xff1b;Potter et al&#xff0c;1994)&#xff0c;耦合了生态系统生产力和土壤碳、氮通量&#xff0c;由网格化的全球气候、辐射、土壤和遥感植被指数数据集驱动。模型包括土壤有机物、微量气体通…

Android Jatpack--ViewModel

1.ViewModel ViewModel是Jetpack的一部分。 ViewModel类旨在以注重生命周期的方式存储和管理界面相关的数据。ViewModel类让数据可在发生屏幕旋转等配置更改后继续留存。 ViewModel出现的背景&#xff1a; ①职责分离 Android开发中&#xff0c;在页面较为简单的情况下&…

【社区分享 - 低代码篇】浪潮低代码引擎UBML和低代码平台inBuilder

【社区分享 - 低代码篇】浪潮低代码引擎UBML和低代码平台inBuilder 文章目录 【社区分享 - 低代码篇】浪潮低代码引擎UBML和低代码平台inBuilder1、inBuilder低代码平台介绍2、inBuilder低代码平台操作指导 1、inBuilder低代码平台介绍 1&#xff09;首先介绍了低代码平台相关背…

分布式应用之zookeeper集群+消息队列Kafka

1.Zookeeper集群的相关知识 1.1 zookeeper的概念 ZooKeeper是一个分布式的&#xff0c;开放源码的分布式应用程序协调服务&#xff0c;是Google的Chubby一个开源的实现&#xff0c;是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件&#xff0c;提供的功能…

00后卷王自述,我真的很卷吗?

前段时间我去面试了一个软件测试公司&#xff0c;成功拿到了offer&#xff0c;薪资也从10k涨到了18k&#xff0c;对于工作都还没两年的我来说&#xff0c;还是比较满意的&#xff0c;毕竟有些工作了3到4年的可能还没有我的高。 在公司一段时间后大家都说我是卷王&#xff0c;其…

CCP4i2之蛋白结构自动构建:Autobuild protein

在解析x射线蛋白晶体结构过程中&#xff0c;最常用的方法就是分子置换&#xff0c;即进行molecular replacement&#xff08;MR&#xff09;时&#xff0c;输入合适的同源蛋白作为model&#xff0c;以及目标蛋白的mtz和sequence&#xff0c;来完成相位解析的过程。 相位求解成…

TDengine 基于SpringBoot 框架和Druid 连接池的TDengine Demo示例

一、前文 TDengine 入门教程——导读 二、JDBC Demo下载 TDengine 官方提供的示例程序源码位于TDengine / TDengine 的 TDengine/examples/JDBC下: JDBCDemo&#xff1a;JDBC 最简单的demo。connectionPools&#xff1a;HikariCP, Druid, dbcp, c3p0 等连接池中使用 taos-jdb…

【刷题之路Ⅱ】迷宫问题升级版——找最短路径

【刷题之路Ⅱ】迷宫问题升级版——找最短路径 一、题目描述二、解题1、方法1——暴力递归更新栈1.1、思路分析1.2、先将栈实现以下1.3、代码实现 一、题目描述 原题连接&#xff1a; 地下迷宫 题目描述&#xff1a; 小青蛙有一天不小心落入了一个地下迷宫,小青蛙希望用自己仅…

C语言深度解析--操作符

目录 操作符 1.算数操作符 2.移位操作符 左移操作符<<&#xff1a; 右移操作符>>&#xff1a; 3.位操作符 按位与&&#xff1a; 按位或 | &#xff1a; 按位异或 ^ &#xff1a; 4.赋值操作符 5.单目操作符 6.关系操作符 7.逻辑操作符 8.条件操作…

这所985复试竟可直接加50分,若复试有科研经历!

本期为大家整理热门院校-“大连理工大学”的择校分析&#xff0c;这个择校分析专题会为大家结合&#xff1a;初试复试占比、复试录取规则&#xff08;是否公平&#xff09;、往年录取录取名单、招生人数、分数线、专业课难度等进行分析。希望能够帮到大家! –所有数据来源于研…

vue:实现简单的拖拽功能

背景 平常做业务很容易遇到拖拽功能&#xff0c;没做之前总觉得会很复杂&#xff0c;今天来看一下到底是怎么实现的。 拖拽API 这是 HTML5 新增的 API&#xff0c;当给元素设置 draggable"true" 的时候&#xff0c;这个元素就可以拖拽了。 <div draggable&quo…

JavaScript全解析——Express框架介绍与入门

本文为千锋资深前端教学老师带来的【JavaScript全解析】系列&#xff0c;文章内含丰富的代码案例及配图&#xff0c;从0到1讲解JavaScript相关知识点&#xff0c;致力于教会每一个人学会JS&#xff01; 文末有本文重点总结&#xff0c;可以收藏慢慢看~ 更多技术类内容&#xf…