题目描述
有5台打印机打印文件,每台打印机有自己的待打印队列。
因为打印的文件内容有轻重缓急之分,所以队列中的文件有1~10不同的代先级,其中数字越大优先级越高。
打印机会从自己的待打印队列中选择优先级最高的文件来打印。
如果存在两个优先级一样的文件,则选择最早进入队列的那个文件。
现在请你来模拟这5台打印机的打印过程。
输入描述
每个输入包含1个测试用例,
每个测试用例第一行给出发生事件的数量N(0 < N < 1000)。
接下来有 N 行,分别表示发生的事件。共有如下两种事件:
- “IN P NUM”,表示有一个拥有优先级 NUM 的文件放到了打印机 P 的待打印队列中。(0< P <= 5, 0 < NUM <= 10);
- “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的优先级,数字越大优先级越高。打印机会从队列中选择优先级最高的任务打印,如果优先级相同,则选择最早进入队列的任务。
输入描述
- 输入包含一个测试用例。
- 第一行给出事件的数量 N (0 < N < 1000)。
- 接下来有 N 行,每行表示发生的事件:
- "IN P NUM": 表示一个优先级为 NUM 的文件放到了打印机 P 的待打印队列中 (0 <= P < 5, 0 < NUM <= 10)。
- "OUT P": 表示打印机 P 进行了一次文件打印,同时该文件从待打印队列中取出 (0 <= P < 5)。
输出描述
对于每个 "OUT P" 事件,输出打印的文件编号。如果队列为空,输出 "NULL"。
实现思路
- 使用一个包含5个元素的列表,每个元素是一个优先级队列(Priority Queue),来表示5台打印机的待打印队列。
- 处理 "IN P NUM" 事件时,将文件加入对应打印机的优先级队列中,文件编号从1开始。
- 处理 "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;
}
代码说明
- PrintJob 结构体:包含文件的优先级、编号和时间戳,定义
<
操作符用于优先级队列的排序。 - 主函数:
- 读取事件数量 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()
代码说明
- PrintJob 类:包含文件的优先级、编号和时间戳,定义
__lt__
方法用于优先级队列的排序。 - 主函数:
- 读取事件数量 N。
- 使用
printers
列表表示5台打印机的优先级队列。 - 处理 "IN P NUM" 事件时,将文件加入对应的优先级队列中。
- 处理 "OUT P" 事件时,从对应的优先级队列中取出文件并输出文件编号。如果队列为空,输出 "NULL"。
使用示例
运行程序时,将按照下述步骤操作:
- 输入事件数量 N。
- 输入每个事件的描述。
- 程序将根据事件的描述输出每次 "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"。