2024华为OD试题及答案-A009-打印机队列

题目描述

有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
说明

问题解析

题目要求模拟5台打印机的打印过程,每台打印机有自己的待打印队列。每个打印任务有1到10的优先级,数字越大优先级越高。打印机会从队列中选择优先级最高的任务打印,如果优先级相同,则选择最早进入队列的任务。

输入描述

  1. 输入包含一个测试用例。
  2. 第一行给出事件的数量 N (0 < N < 1000)。
  3. 接下来有 N 行,每行表示发生的事件:
    • "IN P NUM": 表示一个优先级为 NUM 的文件放到了打印机 P 的待打印队列中 (0 <= P < 5, 0 < NUM <= 10)。
    • "OUT P": 表示打印机 P 进行了一次文件打印,同时该文件从待打印队列中取出 (0 <= P < 5)。

输出描述

对于每个 "OUT P" 事件,输出打印的文件编号。如果队列为空,输出 "NULL"。

实现思路

  1. 使用一个包含5个元素的列表,每个元素是一个优先级队列(Priority Queue),来表示5台打印机的待打印队列。
  2. 处理 "IN P NUM" 事件时,将文件加入对应打印机的优先级队列中,文件编号从1开始。
  3. 处理 "OUT P" 事件时,从对应打印机的优先级队列中取出文件并输出文件编号。如果队列为空,输出 "NULL"。

C++ 实现

以下是实现该逻辑的 C++ 代码:

#include <iostream>
#include <queue>
#include <vector>
#include <string>
using namespace std;

struct PrintJob {
    int priority;
    int id;
    int timestamp;

    bool operator<(const PrintJob& other) const {
        if (priority == other.priority) {
            return timestamp > other.timestamp;  // 先比较优先级,优先级相同时比较时间戳
        }
        return priority < other.priority;  // 优先级大的在前面
    }
};

int main() {
    int N;
    cin >> N;

    vector<priority_queue<PrintJob>> printers(5);
    int job_counter = 1;
    int timestamp = 0;

    for (int i = 0; i < N; ++i) {
        string command;
        cin >> command;
        if (command == "IN") {
            int P, NUM;
            cin >> P >> NUM;
            printers[P].push({NUM, job_counter++, timestamp++});
        } else if (command == "OUT") {
            int P;
            cin >> P;
            if (printers[P].empty()) {
                cout << "NULL" << endl;
            } else {
                PrintJob job = printers[P].top();
                printers[P].pop();
                cout << job.id << endl;
            }
        }
    }

    return 0;
}

代码说明

  1. PrintJob 结构体:包含文件的优先级、编号和时间戳,定义 < 操作符用于优先级队列的排序。
  2. 主函数
    • 读取事件数量 N。
    • 使用 printers 向量表示5台打印机的优先级队列。
    • 处理 "IN P NUM" 事件时,将文件加入对应的优先级队列中。
    • 处理 "OUT P" 事件时,从对应的优先级队列中取出文件并输出文件编号。如果队列为空,输出 "NULL"。

示例输入输出

  • 输入:
7
IN 0 5
IN 1 3
IN 0 4
OUT 0
OUT 1
OUT 0
OUT 0
  • 输出:
1
2
3
NULL

该程序能够根据输入的事件正确模拟5台打印机的打印过程,输出每次 "OUT" 事件时的文件编号。如果队列为空,输出 "NULL"。

Python 实现

import heapq

class PrintJob:
    def __init__(self, priority, job_id, timestamp):
        self.priority = priority
        self.job_id = job_id
        self.timestamp = timestamp

    def __lt__(self, other):
        if self.priority == other.priority:
            return self.timestamp > other.timestamp  # 先比较优先级,优先级相同时比较时间戳
        return self.priority < other.priority  # 优先级大的在前面

def main():
    N = int(input().strip())
    
    printers = [[] for _ in range(5)]
    job_counter = 1
    timestamp = 0

    for _ in range(N):
        command = input().strip().split()
        if command[0] == "IN":
            P = int(command[1])
            NUM = int(command[2])
            heapq.heappush(printers[P], PrintJob(NUM, job_counter, timestamp))
            job_counter += 1
            timestamp += 1
        elif command[0] == "OUT":
            P = int(command[1])
            if not printers[P]:
                print("NULL")
            else:
                job = heapq.heappop(printers[P])
                print(job.job_id)

if __name__ == "__main__":
    main()

代码说明

  1. PrintJob 类:包含文件的优先级、编号和时间戳,定义 __lt__ 方法用于优先级队列的排序。
  2. 主函数
    • 读取事件数量 N。
    • 使用 printers 列表表示5台打印机的优先级队列。
    • 处理 "IN P NUM" 事件时,将文件加入对应的优先级队列中。
    • 处理 "OUT P" 事件时,从对应的优先级队列中取出文件并输出文件编号。如果队列为空,输出 "NULL"。

使用示例

运行程序时,将按照下述步骤操作:

  1. 输入事件数量 N。
  2. 输入每个事件的描述。
  3. 程序将根据事件的描述输出每次 "OUT" 事件时的文件编号。如果队列为空,输出 "NULL"。

示例输入:

7
IN 0 5
IN 1 3
IN 0 4
OUT 0
OUT 1
OUT 0
OUT 0

示例输出:

1
2
3
NULL

该程序能够根据输入的事件正确模拟5台打印机的打印过程,输出每次 "OUT" 事件时的文件编号。如果队列为空,输出 "NULL"。

  • 10
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值