流水线 - 华为OD机试真题(Python 题解)

华为OD机试题库《C++》限时优惠 9.9

华为OD机试题库《Python》限时优惠 9.9

华为OD机试题库《JavaScript》限时优惠 9.9

针对刷题难,效率慢,我们提供一对一算法辅导, 针对个人情况定制化的提高计划(全称1V1效率更高)。

看不懂有疑问需要答疑辅导欢迎私VX: code5bug

华为OD机试真题

题目描述

一个工厂有m条流水线,来并行完成n个独立的作业,该工厂设置了一个调度系统,在安排作业时,总是优先执行处理时间最短的作业。

现给定流水线个数m,需要完成的作业数n, 每个作业的处理时间分别为t1,t2…tn。请你编程计算处理完所有作业的耗时为多少?

当n>m时,首先处理时间短的m个作业进入流水线,其他的等待,当某个作业完成时,依次从剩余作业中取处理时间最短的进入处理。

输入描述

第一行为2个整数(采用空格分隔),分别表示流水线个数m和作业数n;

第二行输入n个整数(采用空格分隔),表示每个作业的处理时长t1,t2…tn。

0 < m,n < 100,0 < t1,t2…tn < 100。

注:保证输入都是合法的。

输出描述

输出处理完所有作业的总时长。

示例1

输入:

3 5
8 4 3 2 10

输出:

13

说明:

1、先安排时间为2、3、4的3个作业。

2、第一条流水线先完成作业,然后调度剩余时间最短的作业8。

3、第二条流水线完成作业,然后调度剩余时间最短的作业10。

4、总工耗时就是第二条流水线完成作业的时间13(3+10)。

题解

这道题目属于模拟调度的应用。我们需要按照作业的处理时间从短到长的顺序调度作业,并在有流水线空闲时立即分配下一个最短的作业。这确保了整体处理时间最短。

解题思路

  1. 排序作业时间:首先将所有作业按照处理时间从短到长排序,以便优先处理短作业。
  2. 初始化流水线:将前m个最短的作业分配给m条流水线。
  3. 模拟处理过程:使用一个队列来管理流水线的完成时间。每次从队列中取出最早完成的流水线,将下一个最短作业分配给它,并更新其完成时间(当前完成时间 + 新作业的处理时间)。
  4. 计算总耗时:最后一个完成的流水线的时间即为所有作业的总耗时。

时间复杂度

  • 排序作业时间:O(n log n),其中n是作业数量。
  • 调度过程:每个作业进出队列一次,每次操作O(1),总时间为O(n)。
  • 总时间复杂度:O(n log n + n) = O(n log n)。

空间复杂度

  • 存储作业时间:O(n)。
  • 队列:O(m)。
  • 总空间复杂度:O(n + m) = O(n)。

Python

"""
@author: code5bug
"""
from collections import deque

# 读取输入:流水线数量m和作业数量n
m, n = map(int, input().split())

# 读取每个作业的处理时间并排序
t = list(map(int, input().split()))
t.sort()  # 升序排序,确保优先处理短作业

# 使用双端队列模拟流水线,存储每条流水线的完成时间
queue = deque()

# 初始化:将前m个最短作业分配给m条流水线
for i in range(min(m, n)):
    queue.append(t[i])

idx = min(m, n)  # 记录下一个待分配作业的索引
last_finish_time = 0  # 记录最后一个作业的完成时间

# 模拟作业调度过程
while queue:
    # 取出最早完成的流水线
    last_finish_time = queue.popleft()

    # 如果还有未分配的作业
    if idx < n:
        # 将该流水线分配给下一个最短作业,并更新其完成时间
        queue.append(last_finish_time + t[idx])
        idx += 1

# 输出最后一个作业的完成时间,即总耗时
print(last_finish_time)

希望这个专栏能让您熟练掌握算法, 🎁🎁🎁 。

整理题解不易, 如果有帮助到您,请给点个赞 ‍❤️‍ 和收藏 ⭐,让更多的人看到。🙏🙏🙏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

什码情况

你的鼓励就是我最大的动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值