• 华为OD机考算法题:食堂供餐


    目录

    题目部分

    解析与思路

    代码实现


    题目部分

    题目食堂供餐
    难度
    题目说明某公司员工食堂以盒饭方式供餐。为将员工取餐排队时间降低为0,食堂的供餐速度必须要足够快。现在需要根据以往员工取餐的统计信息,计算出一个刚好能达成排队时间为0的最低供餐速度。即,食堂在每个单位时间内必须至少做出多少份盒饭才能满足要求。
    输入描述第1行为一个正整数N,表示食堂开餐时长。1 <= N <= 1000。
    第2行为一个正整数M,表示开餐前食堂已经准备好的盒饭份数。pi <= M <= 1000。
    第3行为N个正整数,用空格分隔,依次表示开餐时间内按时间顺序每个单位时间进入食堂取餐的人数Pi。1 <=i<= N,0<= Pi<=100。
    输出描述一个整数,能满足题目要求的最低供餐速度(每个单位时间需要做出多少份盒饭)。
    补充说明每人只取一份盒饭。
    需要满足排队时间为0,必须保证取餐员工到达食堂时,食堂库存盒饭数量不少于本次来取餐的人数。
    第一个单位时间来取餐的员工只能取开餐前食堂准备好的盒饭。
    每个单位时间里制作的盒饭只能供应给后续单位时间来的取餐的员工。
    食堂在每个单位时间里制作的盒饭数量是相同的。
    ------------------------------------------
    示例
    示例1
    输入3
    14
    10 4 5
    输出3
    说明本样例中,总共有3批员工就餐,每批人数分别为10、4、5。
    开餐前食堂库存14份。
     
    食堂每个个单位时间至少要做出3份餐饭才能达成排队时间为0的目标。具体情况如下:
    第一个单位时间来的10位员工直接从库存取餐。取餐后库存剩余4份盒饭,加上第一个单位时间做出的3份,库存有7份。
    第二个单位时间来的4员工从库存的7份中取4份。取餐后库存剩余3份盒饭,加上第二个单位时间做出的3份,库存有6份。
    第三个单位时间来的员工从库存的6份中取5份,库存足够。
      
    如果食堂在单位时间只能做出2份餐饭,则情况如下:
    第一个单位时间来的10位员工直接从库存取餐。取餐后库存剩余4份盒饭,加上第一个单位时间做出的2份,库存有6份。
    第二个单位时间来的4员工从库存的6份中取4份。取餐后库存剩余2份盒饭,加上第二个单位时间做出的2份,库存有4份。
    第三个单位时间来的员工需要取5份,但库存只有4份,库存不够。

    解析与思路

    题目解读

    此题中,第1行是就餐员工的总批数,设为 count;第2行是初始库存数,设为 stockQty;第3行是每批次的份数,假设每批次的数字放到数组 dinners 中,那么dinners的长度为count,且dinners[i] 即为第 ( i + 1 ) 个批次所需的份数(备注:批次起始值为1,放到数组的第 0 个元素)。

    假设题目中最低的供餐速度为 x(x为正整数),那么 对于所有的 i ( 0 <= i <= count),x 必须满足 ( stockQty + x * i) >=  idx=0idinners[idx]" role="presentation" style="position: relative;">idx=0idinners[idx]。其中, idx=0idinners[idx]" role="presentation" style="position: relative;">idx=0idinners[idx] 代表着dinners数组的前 i 个元素之和,即 idx=0idinners[idx]" role="presentation" style="position: relative;">idx=0idinners[idx] = dinners[0] + dinners[1] + … + dinners[i]。

    分析思路

    虽然此题的难度设置为“难”,实际解题思路比较简单。

    设置 x 的初始值为0。

    根据不等式 ( stockQty + x * i) >=  idx=0idinners[idx]" role="presentation" style="position: relative;">idx=0idinners[idx],对于 i, 从 0 到 ( count -1 ) ,判断当前的 x 值是否保证不等式成立:

    • 如果不等式成立,则不进行任何操作;
    • 如果不等式不成立,即 x 值过小,重新计算 x 的值。计算后,x 的新值必定比老值大。
      我们知道,当 从 0 到 ( i - 1 ), x 的老值都能保证不等式成立,当 x 值变大,不等式的左边比以前更大。这意味着当 x 取新值(更大的值)时,这个不等式在 0 到 ( i - 1 )  一定是成立的。

    遍历完后,计算出的 x 即为题目要求的值。

    此算法只需要遍历一次 dinners 数组,时间复杂度为 O(n);由于使用了辅助数组,其空间复杂度也为 O(n)。


    代码实现

    Java代码

    1. import java.util.Scanner;
    2. /**
    3. * 食堂供餐
    4. *
    5. * @since 2023.09.13
    6. * @version 0.2
    7. * @author Frank
    8. *
    9. */
    10. public class Dinners {
    11. public static void main(String[] args) {
    12. Scanner sc = new Scanner(System.in);
    13. while (sc.hasNext()) {
    14. // 第一行输入就餐的批次
    15. String strCount = sc.nextLine();
    16. int count = Integer.parseInt(strCount);
    17. // 第二行输入初始库存数
    18. String strStockQty = sc.nextLine();
    19. int stockQty = Integer.parseInt(strStockQty);
    20. // 第三行输入每批次所需的午餐份数
    21. // 此处dinners中的元素都是String,后面需要转换成int处理
    22. String strDinners = sc.nextLine();
    23. String[] dinners = strDinners.split(" "); // dinners.length == count
    24. processDinners(count, stockQty, dinners);
    25. }
    26. }
    27. private static void processDinners(int count, int stockQty, String[] dinners) {
    28. int currentSumNeeded = 0;
    29. int x = 0;
    30. int currentStock = stockQty;
    31. for (int i = 0; i < count; i++) {
    32. currentStock = stockQty + i * x;
    33. currentSumNeeded += Integer.parseInt(dinners[i]);
    34. if (currentStock < currentSumNeeded) {
    35. // 计算最小的 x(新值必定比当前的x大),确保 currentStock >= currentSumNeeded
    36. int diff = currentSumNeeded - stockQty;
    37. int tmpX = diff / i;
    38. if (diff % i != 0) {
    39. tmpX++;
    40. }
    41. x = tmpX;
    42. }
    43. }
    44. System.out.println(x);
    45. }
    46. }

    JavaScript代码

    1. const rl = require("readline").createInterface({ input: process.stdin });
    2. var iter = rl[Symbol.asyncIterator]();
    3. const readline = async () => (await iter.next()).value;
    4. void async function() {
    5. while (line = await readline()) {
    6. // 第一行,进餐的批次
    7. var count = parseInt(line);
    8. // 第二行,初始库存数
    9. var strStockQty = await readline();
    10. var stockQty = parseInt(strStockQty);
    11. // 第三行,每批次需要的份数
    12. var initDinners = await readline();
    13. var strDinners = initDinners.split(" ");
    14. processDinners(count, stockQty, strDinners);
    15. }
    16. }();
    17. function processDinners(count, stockQty, strDinners) {
    18. var currentSumNeeded = 0;
    19. var x = 0;
    20. var currentStock = stockQty;
    21. for (var i = 0; i < count; i++) {
    22. currentStock = stockQty + i * x;
    23. currentSumNeeded += parseInt(strDinners[i]);
    24. if (currentStock < currentSumNeeded) {
    25. // 计算最小的 x(新值必定比当前的x大),确保 currentStock >= currentSumNeeded
    26. var diff = currentSumNeeded - stockQty;
    27. var tmpX = parseInt(diff / i);
    28. if (diff % i != 0) {
    29. tmpX++;
    30. }
    31. x = tmpX;
    32. }
    33. }
    34. console.log(x);
    35. }

    (完)

  • 相关阅读:
    SpringBoot-AOP-基础到进阶
    Java 复习笔记 - 集合进阶篇:数据结构
    前缀和题型总结 I: leetcode 467、795、904、992、1109
    Thymeleaf th:fragment局部刷新
    常见git提交规范
    [附源码]Python计算机毕业设计SSM教学团队管理系统(程序+LW)
    Python入门系列(十)一篇学会python文件处理
    基于大数据的工业设备故障诊断模型设计
    JSP application 对象
    Flutter高仿微信-第53篇-群聊-删除并退出
  • 原文地址:https://blog.csdn.net/ZiJinShi/article/details/132677015