华为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 = 13)。 |
解读与分析
题目解读:
把所有的作业按照从小到的顺序排序,依次放到流水线中。当某个流水线完成,从作业的队列中拿出下一个,放到流水线中。求最终所有作业完成的时间。
分析与思路:
此题先对作业从小到大排序。
当流水线数大于作业数,则输入作业中最大的值。
当流水线数小于作业数,
1. 设作业时间为 sum,初始值为 0。将排序好的作业依次放到流水线中。
2. 计算流水线中最小值,设为 min,赋值 sum += min,并把流水中的所有作业都减去 min,然后把下一个作业放到值为 0 流水线中,循环,直到最后一个作业放到流水线中。
3. 最后一次的时间为流水线中的最大值(设为max),并 sum += max。输出 sum。
时间复杂度和空间复杂度均为 O(n)。
代码实现
Java代码
import java.util.Arrays;
import java.util.Scanner;
/**
* 流水线
*
* @since 2023.10.25
* @version 0.1
* @author Frank
*
*/
public class Pipeline {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
String input = sc.nextLine();
String[] inputStr = input.split(" ");
int m = Integer.parseInt(inputStr[0]);
int n = Integer.parseInt(inputStr[1]);
int[] workInfo = new int[n];
input = sc.nextLine();
inputStr = input.split(" ");
for (int i = 0; i < n; i++) {
workInfo[i] = Integer.parseInt(inputStr[i]);
}
processPipeline(m, n, workInfo);
}
}
private static void processPipeline(int m, int n, int[] workInfo) {
Arrays.sort(workInfo);
if (m >= n) {
System.out.println(workInfo[n - 1]);
return;
}
int[] pipeline = new int[m];
int sum = workInfo[0];
int minIndex = 0;
int Value2Minus = workInfo[0];
for (int i = 0; i < m; i++) {
pipeline[i] = workInfo[i] - Value2Minus;
}
int workIndex = m;
while (workIndex <= n - 1) {
pipeline[minIndex] = workInfo[workIndex];
if (workIndex == n - 1) {
sum += pipeline[getMaxPipepline(pipeline)];
break;
} else {
minIndex = getMinPipepline(pipeline);
Value2Minus = pipeline[minIndex];
sum += Value2Minus;
for (int i = 0; i < m; i++) {
pipeline[i] -= Value2Minus;
}
}
workIndex++;
}
System.out.println(sum);
}
private static int getMinPipepline(int[] pipeline) {
int index = 0;
int min = pipeline[0];
for (int i = 0; i < pipeline.length; i++) {
if (pipeline[i] < min) {
index = i;
min = pipeline[i];
}
}
return index;
}
private static int getMaxPipepline(int[] pipeline) {
int index = 0;
int max = pipeline[0];
for (int i = 0; i < pipeline.length; i++) {
if (pipeline[i] > max) {
index = i;
max = pipeline[i];
}
}
return index;
}
}
JavaScript代码
const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
void async function() {
while (line = await readline()) {
var inputArr = line.split(" ");
var m = parseInt(inputArr[0]);
var n = parseInt(inputArr[1]);
var workInfo = new Array();
line = await readline();
var inputStr = line.split(" ");
for (var i = 0; i < n; i++) {
workInfo[i] = parseInt(inputStr[i]);
}
processPipeline(m, n, workInfo);
}
}();
function processPipeline(m, n, workInfo) {
workInfo.sort(function compareFn(a, b) {
return a - b;
});
console.log( workInfo );
if (m >= n) {
console.log(workInfo[n - 1]);
return;
}
var pipeline = new Array();
var sum = workInfo[0];
var minIndex = 0;
var value2Minus = workInfo[0];
for (var i = 0; i < m; i++) {
pipeline[i] = workInfo[i] - value2Minus;
}
console.log( pipeline );
var workIndex = m;
while (workIndex <= n - 1) {
pipeline[minIndex] = workInfo[workIndex];
if (workIndex == n - 1) {
sum += pipeline[getMaxPipepline(pipeline)];
break;
} else {
minIndex = getMinPipepline(pipeline);
value2Minus = pipeline[minIndex];
sum += value2Minus;
for (var i = 0; i < m; i++) {
pipeline[i] -= value2Minus;
}
console.log( pipeline );
}
workIndex++;
}
console.log(sum);
}
function getMinPipepline(pipeline) {
var index = 0;
var min = pipeline[0];
for (var i = 0; i < pipeline.length; i++) {
if (pipeline[i] < min) {
index = i;
min = pipeline[i];
}
}
return index;
}
function getMaxPipepline(pipeline) {
var index = 0;
var max = pipeline[0];
for (var i = 0; i < pipeline.length; i++) {
if (pipeline[i] > max) {
index = i;
max = pipeline[i];
}
}
return index;
}
(完)