(新A卷,100分)- 执行时长(Java & JS & Python)华为OD

(新A卷,100分)- 执行时长(Java & JS & Python)华为OD

题目描述

为了充分发挥GPU算力,需要尽可能多的将任务交给GPU执行,现在有一个任务数组,数组元素表示在这1秒内新增的任务个数且每秒都有新增任务。

假设GPU最多一次执行n个任务,一次执行耗时1秒,在保证GPU不空闲情况下,最少需要多长时间执行完成。

输入描述
  • 第一个参数为GPU一次最多执行的任务个数,取值范围[1, 10000]
  • 第二个参数为任务数组长度,取值范围[1, 10000]
  • 第三个参数为任务数组,数字范围[1, 10000]

输出描述
  • 执行完所有任务最少需要多少秒。

用例
输入

3
5
1 2 3 4 5

输出6
说明一次最多执行3个任务,最少耗时6s
输入

4
5
5 4 1 1 1

输出5
说明一次最多执行4个任务,最少耗时5s

题目解析

题干中有一个段话很关键:"数组元素表示在这1秒内新增的任务个数且每秒都有新增任务",也就是说,数组中的任务个数不是一次性push完的,而是每过1s才push一次,而这刚好和GPU单次执行时间1s相温吻合。

比如

4

5

5 4 1 1 1

第1s时,任务数组中只有一个元素5,

然后GPU开始将这5个任务接收处理,但是1s时间,GPU只能处理4个,因此第1s结束后,还剩余1个任务没处理完。

第2s时,任务数组又加入一个元素4,

然后GPU将新增的4个任务接收处理,但是上一次还遗留1个任务没处理完,而GPU在1s内只能处理4个任务,因此本轮会遗留1个任务

第3s时,任务数组又加入一个元素1,

然后GPU将新增的1个任务接收处理,,但是上一次还遗留1个任务没处理完,而GPU在1s内只能处理4个任务,因此本轮不会遗留任务。

第4s时,任务数组又加入一个元素1,

由于没有遗留任务,且GPU在1s可以处理4个,因此本轮不会遗留任务

第5s时,任务数组又加入一个元素1,

由于没有遗留任务,且GPU在1s可以处理4个,因此本轮不会遗留任务

因此GPU需要花费5s来处理完所有任务。

同理可得

3

5

1 2 3 4 5

需要花费6s来处理所有任务。

但是这种逻辑似乎和题目要求得 “在保证GPU不空闲情况下,最少需要多长时间执行完成”

比如用例1中,

  • 第1s只有1个任务需要处理,但是GPU最多可以处理3个,因此会发生GPU空闲
  • 第2s只有2个任务需要处理,但是GPU最多可以处理3个,因此会发生GPU空闲
  • 第3s有3个任务需要处理,但是GPU最多可以处理3个,此时不会发生GPU空闲
  • 第4s有4个任务需要处理,但是GPU最多可以处理3个,此时不会发生GPU空闲,并还会遗留1个任务到下一轮
  • 第5s有5个任务需要处理,但是GPU最多可以处理3个,并且还有上一秒遗留得1个任务,因此GPU会满载运行,并且会遗留3个任务到下一轮。

我们可以发现第1s,2s都发生了GPU空闲,那么有没有办法解决GPU空闲呢?

最直接的办法就是让每秒新增任务最多的放到前面交给GPU执行,比如第1s执行5,第2s执行4,按照这种逻辑,一共只需要5s。

但是这个逻辑结果不符合用例输出,也就是说,我们不能更改任务数组中任务个数的顺序,nima,那题目里面最后要求“最少”是什么意思?故意迷惑人的吗?

Java算法源码
import java.util.Scanner;

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

    int maxCount = sc.nextInt();

    int n = sc.nextInt();
    int[] tasks = new int[n];
    for (int i = 0; i < n; i++) tasks[i] = sc.nextInt();

    System.out.println(getResult(maxCount, tasks));
  }

  public static int getResult(int maxCount, int[] tasks) {
    int time = 0;
    int remain = 0;

    for (int task : tasks) {
      if (task + remain > maxCount) {
        remain = task + remain - maxCount;
      } else {
        remain = 0;
      }
      time++;
    }

    while (remain > 0) {
      remain -= maxCount;
      time++;
    }

    return time;
  }
}

JS算法源码
/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");

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

const lines = [];
rl.on("line", (line) => {
  lines.push(line);

  if (lines.length === 3) {
    let maxCount = parseInt(lines[0]);
    let tasksLen = parseInt(lines[1]);
    let tasks = lines[2]
      .split(" ")
      .slice(0, tasksLen)
      .map((ele) => parseInt(ele));

    console.log(getMinTime(maxCount, tasks));

    lines.length = 0;
  }
});

function getMinTime(maxCount, tasks) {
  let time = 0;
  let remain = 0;

  for (let i = 0; i < tasks.length; i++) {
    if (tasks[i] + remain > maxCount) {
      remain = tasks[i] + remain - maxCount;
    } else {
      remain = 0;
    }
    time++;
  }

  while (remain > 0) {
    remain -= maxCount;
    time++;
  }

  return time;
}

Python算法源码
# 输入获取
maxCount = int(input())
n = int(input())
tasks = list(map(int, input().split()))


# 算法入口
def getResult():
    time = 0
    remain = 0

    for task in tasks:
        if task + remain > maxCount:
            remain = task + remain - maxCount
        else:
            remain = 0
        time += 1

    while remain > 0:
        remain -= maxCount
        time += 1

    return time


# 算法调用
print(getResult())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值