【华为OD机考 统一考试机试】 任务总执行时长(C++ Java JavaScript Python )

73 阅读5分钟

华为OD机考:统一考试 C卷 + D卷 + B卷 + A卷

2023年11月份,华为官方已经将 华为OD机考:OD统一考试(A卷 / B卷)切换到 OD统一考试(C卷)和 OD统一考试(D卷) 。根据考友反馈:目前抽到的试卷为B卷或C卷/D卷,其中C卷居多 ,按照之前的经验C卷部分考题会复用A卷,B卷题,博主正积极从考过的同学收集C卷和D卷真题。 可以先继续刷B卷, C卷和D卷的题目会放在现在大家购买的专栏内,不需要重新购买,请大家放心。

专栏:2023华为OD机试( A卷+B卷+C卷+D卷)(C++JavaJSPy)\

华为OD面试真题精选:华为OD面试真题精选

在线OJ:点击立即刷题,模拟真实机考环境

题目描述

任务编排服务负责对任务进行组合调度。

参与编排的任务有两种类型,其中一种执行时长为taskA,另一种执行时长为taskB。

任务一旦开始执行不能被打断,且任务可连续执行。

服务每次可以编排num个任务。

请编写一个方法,生成每次编排后的任务所有可能的总执行时长。

输入描述

第1行输入分别为第1种任务执行时长taskA,

第2种任务执行时长taskB,

这次要编排的任务个数num,以逗号分隔。

注:每种任务的数量都大于本次可以编排的任务数量

  • 0 < taskA
  • 0 < taskB
  • 0 <= num <= 100000

输出描述

数组形式返回所有总执行时时长,需要按从小到大排列。

用例

输入: 1,2,3 输出: [3, 4, 5, 6] 说明: 可以执行 3 次 taskA,得到结果 3: 执行 2次 taskA和 次 taskB,得到结果 4。以此类推,得到最终结果.

题目解析

这其实就是求每种排列的和

比如用例中,有三个任务,那么有如下组合:

  • 三个1
  • 两个1,一个2
  • 一个1,两个2
  • 三个2

无论每个组合,能编排成几个排列,其实执行总时长,即排列的和都是一样的

  • 三个1:和为3
  • 两个1,一个2:和为4
  • 一个1,两个2:和为5
  • 三个2:和为6

代码思路

这道题目需要计算出所有可能的任务组合情况,并计算每种组合情况的总执行时长。可以采用遍历的方式,枚举任务 B 的数量(假设为 i),则任务 A 的数量为 num-i。对于每个 i,计算出对应的总执行时长,将其添加到 set 中,最后输出 set 中的所有元素即可。由于 set 自动排序且去重,因此可以保证输出结果按从小到大排列且没有重复元素。

具体代码实现可以先读取输入,获取任务 A 和任务 B 的处理时间以及总任务数,然后遍历所有可能的任务组合情况,计算出每种组合情况的总执行时长,并将其添加到 set 中。最后遍历 set 中的所有元素,输出结果即可。

C++

#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
using namespace std;

vector<int> getPossibleTotalDuration(int taskADuration, int taskBDuration, int numTasks) {
    if (numTasks == 0) {
        return vector<int>();
    }

    // 如果第一种任务和第二种任务的执行时长相同,直接返回总执行时长
    if (taskADuration == taskBDuration) {
        return vector<int>({taskADuration * numTasks});
    }

    set<int> possibleDurations;
    for (int i = 0; i <= numTasks; i++) {
        possibleDurations.insert(taskADuration * i + taskBDuration * (numTasks - i));
    }

    return vector<int>(possibleDurations.begin(), possibleDurations.end());
}

int main() {
    // 读入输入的任务执行时长和任务个数
    string input;
    cin >> input;
    vector<int> taskDurations;
    size_t pos = 0;
    while ((pos = input.find(",")) != string::npos) {
        taskDurations.push_back(stoi(input.substr(0, pos)));
        input.erase(0, pos + 1);
    }
    taskDurations.push_back(stoi(input));

    // 输出每次编排后的任务所有可能的总执行时长
    vector<int> possibleDurations = getPossibleTotalDuration(taskDurations[0], taskDurations[1], taskDurations[2]);
    cout << "[";
    for (int i = 0; i < possibleDurations.size(); i++) {
        cout << possibleDurations[i];
        if (i != possibleDurations.size() - 1) {
            cout << ",";
        }
    }
    cout << "]" << endl;

    return 0;
}

JavaScript

const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

// 监听输入事件
rl.on("line", (line) => {
  // 将输入的字符串转换为数字
  const [durationA, durationB, num] = line.split(",").map(Number);

  // 如果任务数为0,则返回空数组
  if (num == 0) {
    console.log([]);
      return ;
  }

  // 如果任务A和任务B的执行时间相等,则总执行时间为任务A的执行时间乘以任务数
  if (durationA === durationB) {
    console( [durationA * num]);
      return;
  }

  // 使用Set来存储所有可能的总执行时间,避免重复
  const result = new Set();

  // 遍历所有可能的任务A的执行次数
  for (let i = 0; i <= num; i++) {
    // 计算任务A和任务B的总执行时间,并将其添加到Set中
    result.add(durationA * i + durationB * (num - i));
  }

  // 将Set转换为数组,并按从小到大的顺序排序
  const ans = [...result].sort((a, b) => a - b);

  // 输出结果
  console.log(ans);
});

Java

import java.util.Arrays;
import java.util.Scanner;
import java.util.TreeSet;

public class Main {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);

    // 读入输入的任务执行时长和任务个数
    String input = scanner.next();
    Integer[] taskDurations = Arrays.stream(input.split(",")).map(Integer::parseInt).toArray(Integer[]::new);

    // 输出每次编排后的任务所有可能的总执行时长
    System.out.println(getPossibleTotalDuration(taskDurations[0], taskDurations[1], taskDurations[2]));
  }

  /**
   * 获取每次编排后的任务所有可能的总执行时长
   * @param taskADuration 第一种任务的执行时长
   * @param taskBDuration 第二种任务的执行时长
   * @param numTasks 每次编排的任务个数
   * @return 可能的总执行时长
   */
  public static String getPossibleTotalDuration(int taskADuration, int taskBDuration, int numTasks) {
    if (numTasks == 0) {
      return "[]";
    }

    // 如果第一种任务和第二种任务的执行时长相同,直接返回总执行时长
    if (taskADuration == taskBDuration) {
      return Arrays.toString(new int[] {taskADuration * numTasks});
    }

    TreeSet<Integer> possibleDurations = new TreeSet<>();
    for (int i = 0; i <= numTasks; i++) {
      possibleDurations.add(taskADuration * i + taskBDuration * (numTasks - i));
    }

    return possibleDurations.toString();
  }
}

Python

def get_possible_total_duration(task_a_time, task_b_time, num_of_tasks):
    if num_of_tasks == 0:
        return []

    if task_a_time == task_b_time:
        return [task_a_time * num_of_tasks]

    durations = set()
    for i in range(num_of_tasks + 1):
        durations.add(task_a_time * i + task_b_time * (num_of_tasks - i))

    return sorted(list(durations))

task_a_time, task_b_time, num_of_tasks = map(int, input().split(","))
print(get_possible_total_duration(task_a_time, task_b_time, num_of_tasks))

@[TOC]

doutub_gif