OD 算法题 B卷【模拟工作队列】
文章目录
- 模拟工作队列
模拟工作队列
- 有一个任务提交者,若干任务执行者(从1开始编号),提交者会在给定的时刻向队列中提交任务,任务有执行所需的时间;
- 执行者取出任务的时刻加上执行时间即为任务完成的时刻;
- 编号小的执行者优先级高,执行者空闲时则取任务并执行,多个执行者空闲时,优先级高的优先取任务;
- 当工作队列满时,提交的新任务入队,(没有执行者空闲时)最老的任务丢弃,否则取出最老的任务执行;
输入描述:
第一行输入2N个正整数,表示N个任务的提交时刻、执行时间;提交时刻不会重复,并按照提交时刻升序排序;N <= 20
第二行输入两个数字,表示队列的最大长度、执行者的数量;
输出描述:
输出两个数字,分别表示最后一个任务执行完成的时刻、被丢弃的任务数量,空格分隔
示例1
输入:
1 3 2 2 3 3
3 2
输入:
7 0
示例2
输入:
1 6 2 4 4 3 6 3
1 2
输出:
10 0
示例3
输入:
1 6 2 4 3 3 4 3 6 3
1 2
输出:
10 1
python实现:
- xx
tasks = list(map(int, input().strip().split()))
queue_len, consumer_num = list(map(int, input().strip().split()))
task_queue = []# 任务按照时刻划分元组
task_list = []
max_time = 0
for i in range(0, len(tasks), 2):task_list.append([tasks[i], tasks[i+1]])max_time = max(max_time, tasks[i] + tasks[i+1])def is_full():global task_queue, queue_lenreturn len(task_queue) == queue_len# 丢弃的任务计数
drop_task = 0
last_time = 0 # 最后任务的执行结束时刻
# 记录执行者的状态
consumers = [0 for _ in range(consumer_num)]# 时刻轴设定
for t in range(1, max_time + 3):# 判断执行者是否执行任务结束for c_idx in range(consumer_num):if consumers[c_idx] == 0:continueif t >= consumers[c_idx][-1]:consumers[c_idx] = 0last_time = t# 任务入队if task_list and task_list[0][0] == t: # 当前时刻的任务入队cur_task = task_list.pop(0)if not is_full():# 任务入队task_queue.insert(0, cur_task)else:# 有空闲的执行者,则取出一个任务执行,并将最新的任务入队for c_idx in range(consumer_num):if consumers[c_idx] == 0: # 空闲# 取出一个任务start, duration = task_queue.pop()consumers[c_idx] = [t, duration, t + duration]# 新任务入队task_queue.insert(0, cur_task)breakelse:# 没有空闲的执行者,任务丢弃task_queue.pop()drop_task += 1# 新任务入队task_queue.insert(0, cur_task)# 执行者执行任务for c_idx in range(consumer_num):# 有空闲,且有任务if consumers[c_idx] == 0 and task_queue:start, duration = task_queue.pop()consumers[c_idx] = [t, duration, t + duration] # 从获取任务的时刻开始计时print(str(last_time) + " " + str(drop_task))