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

news/2024/7/20 16:49:01 标签: 算法, 华为OD, Java, JavaScript, 数据结构

目录

题目部分

解析与思路

代码实现


题目部分

题目食堂供餐
题目说明某公司员工食堂以盒饭方式供餐。为将员工取餐排队时间降低为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) >=  \sum_{idx=0}^{i} dinners[idx]。其中, \sum_{idx=0}^{i} dinners[idx] 代表着dinners数组的前 i 个元素之和,即 \sum_{idx=0}^{i} dinners[idx] = dinners[0] + dinners[1] + … + dinners[i]。

分析思路

设置 x 的初始值为0。

根据不等式 ( stockQty + x * i) >=  \sum_{idx=0}^{i} dinners[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代码

import java.util.Scanner;

/**
 * 食堂供餐
 * @since 2023.09.05
 * @version 0.1
 * @author Frank
 *
 */
public class Dinners {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);

		// 第一行输入就餐的批次
		String strCount = sc.nextLine();
		int count = Integer.parseInt( strCount );
		
		// 第二行输入初始库存数
		String strStockQty = sc.nextLine();
		int stockQty = Integer.parseInt( strStockQty );
		
		// 第三行输入每批次所需的午餐份数
		// 此处dinners中的元素都是String,后面需要转换成int处理
		String strDinners = sc.nextLine();
		String[] dinners = strDinners.split(" "); // dinners.length == count
				
		int currentSumNeeded = 0;
		int x = 0;
		int currentStock = stockQty;
		for( int i = 0; i < count; i ++ )
		{
			currentStock = stockQty + i * x;
			currentSumNeeded += Integer.parseInt( dinners[i] );	
			if( currentStock < currentSumNeeded )
			{
				// 计算最小的 x(新值必定比当前的x大),确保 currentStock >= currentSumNeeded
				int diff = currentSumNeeded - stockQty;
				int tmpX =  diff / i;
				if( diff % i != 0 )
				{
					tmpX ++;
				}
				x = tmpX;
			}
		}
		System.out.println( x );
	}
}

JavaScript代码

const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
void async function() {
    let input = [];
    while (line = await readline()) {
        input.push(line);
    }

    // 第一行,进餐的批次
    var strCount = input[0];
    var count = parseInt(strCount);

    // 第二行,初始库存数
    var strStockQty = input[1];
    var stockQty = parseInt(strStockQty);

    // 第三行,每批次需要的份数
    var strDinners = input[2].split(" ");

    var currentSumNeeded = 0;
    var x = 0;
    var currentStock = stockQty;
    for (var i = 0; i < count; i++) {
        currentStock = stockQty + i * x;
        currentSumNeeded += parseInt(strDinners[i]);
        if (currentStock < currentSumNeeded) {
            // 计算最小的 x(新值必定比当前的x大),确保 currentStock >= currentSumNeeded
            var diff = currentSumNeeded - stockQty;
            var tmpX = parseInt(diff / i);
            if (diff % i != 0) {
                tmpX++;
            }
            x = tmpX;
        }
    }
    console.log(x);
}();

(完)


http://www.niftyadmin.cn/n/5001104.html

相关文章

Kubernetes单主集群的部署(一)

目录 一、k8s单主架构集群的部署 1.操作系统初始化配置 2.部署 etcd 集群 3.部署docker引擎 4.部署 Master 组件 5.部署 Worker Node 组件 6.部署 CNI 网络组件&#xff08;使用 flannel&#xff09; 一、k8s单主架构集群的部署 k8s集群master01&#xff1a;192.168.1…

高速信号应如何走线?这些规则千万别走错

提起高速信号的设计与布线&#xff0c;可能很多工程师都能头头是道&#xff0c;但放在实际设计中却大部分不可行&#xff0c;这篇文章将向电子工程师介绍一些关键规则&#xff0c;确保在电路板上传输高速信号时获得最佳性能&#xff0c;注意这些规则千万别走错&#xff01; 1、…

电子半导体行业电能质量监测与治理系统解决方案 安科瑞 许敏

摘要&#xff1a;在国家鼓励半导体材料国产化的政策导向下&#xff0c;本土半导体材料厂商不断提升半导体产品技术水平和研发能力&#xff0c;逐渐打破了国外半导体厂商的垄断格局&#xff0c;推进中国半导体材料国产化进程&#xff0c;促进中国半导体行业的发展。半导体产品的…

Git 设置和清除用户名和邮箱

作为一款十分流行的版本控制工具&#xff0c;Git 得到了越来越多的开发者的喜爱。然而&#xff0c;当使用 Git 上传代码的时候&#xff0c;很多开发者都会遇到一个问题&#xff0c;那就是如果在提交代码时错误地设置了用户名和邮箱&#xff0c;那么这些信息就会被永久地记录在 …

递归/回溯/动规

1 动规-打家劫舍一 你是一个经验丰富的小偷&#xff0c;准备偷沿街的一排房间&#xff0c;每个房间都存有一定的现金&#xff0c;为了防止被发现&#xff0c;你不能偷相邻的两家&#xff0c;即&#xff0c;如果偷了第一家&#xff0c;就不能再偷第二家&#xff1b;如果偷了第二…

大厂面试 | 百度一面,顶不住

题目来源&#xff1a;https://www.nowcoder.com/feed/main/detail/d39aabc0debd4dba810b4b9671d54348 前文 本期是【捞捞面经】系列文章的第 2 期&#xff0c;持续更新中…。&#xff08;更多与往期下方仓库直达&#xff09; 《捞捞面经》系列正式开始连载啦&#xff0c;据说看…

解决vue项目首行报红( ESLint 配置)和新建的vue文件首行报红问题

目录 前情提要&#xff1a; 修改ESLint 配置 新建的vue文件首行还是报红 报红原因&#xff1a; 解决方法&#xff1a; 前情提要&#xff1a; 在网上查到的方法可能是在package.json文件或者.eslintrc.js文件中添加 requireConfigFile: false 如果此方法对你的错误不起作用…

书单怎么制作?有哪些技巧和注意事项?

书单是指将自己喜欢的书籍、影视作品等进行整理和推荐&#xff0c;供他人参考的清单。它可以是一个人的私人书单&#xff0c;也可以是一个团队或者社群共享的书单&#xff0c;我们在一些短视频媒体上应该都有看到过一些制作的书单视频分享&#xff0c;那么如果我们也想上传书单…