华为OD机试真题——机房布局(2025B卷:100分)Java/python/JavaScript/C++最佳实现
2025 B卷 100分 题型
本专栏内全部题目均提供Java、python、JavaScript、C++等多种语言的最佳实现方式;
并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析;
本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分享》
华为OD机试真题《机房布局》:
文章快捷目录
题目描述及说明
Java
python
JavaScript
C++
题目名称:机房布局
- 知识点:字符串、贪心算法(或栈操作)、逻辑处理
- 时间限制:1秒
- 空间限制:256MB
- 限定语言:不限
题目描述
小明正在规划一个大型数据中心机房,为了使得机柜上的机器都能正常满负荷工作,需要确保在每个机柜边上至少要有一个电箱。为了简化题目,假设这个机房是一整排,M
表示机柜,I
表示间隔,请你返回这整排机柜至少需要多少个电箱。如果无解请返回-1
。
输入描述
一个字符串cabinets
,其中M
表示机柜,I
表示间隔。字符串长度满足1 ≤ strlen(cabinets) ≤ 10000
。
例如:
- 输入:
"MIIM"
其中M
表示机柜,I
表示间隔。
输出描述
返回整排机柜至少需要多少个电箱。
- 示例1输入:
"MIIM"
,输出:2
- 示例2输入:
"MIM"
,输出:1
- 示例3输入:
"M"
,输出:-1
- 示例4输入:
"MMM"
,输出:-1
- 示例5输入:
"I"
,输出:0
补充说明
1 ≤ strlen(cabinets) ≤ 10000
,且cabinets[i]
为'M'
或'I'
。- 若机柜(
M
)前后均无间隔(I
),则无法满足条件,返回-1
。 - 电箱需放置在间隔(
I
)上,且一个I
可同时满足相邻M
的需求。
Java
问题分析
我们需要在机房布局字符串中放置电箱,确保每个机柜(M)至少有一个相邻的电箱(放置在间隔I上)。一个电箱可以同时满足左右相邻的两个机柜。如果无法满足所有机柜,则返回-1。
核心挑战:
- 机柜覆盖规则:每个机柜必须至少有一个相邻电箱(左或右)
- 电箱共享:一个电箱可以覆盖左右两个机柜
- 边界处理:处理字符串开头和结尾的特殊情况
- 无解情况:当机柜无法被覆盖时返回-1
解题思路
使用贪心算法解决此问题:
-
遍历处理每个机柜(M):
- 检查是否已被前一个电箱覆盖
- 优先在右侧放置电箱(为后续机柜提供覆盖)
- 次选在左侧放置电箱(当前机柜无法右侧覆盖时)
- 左右都无法放置则返回-1
-
电箱放置策略:
- 使用布尔数组记录电箱位置
- 优先选择右侧放置(最大化电箱利用率)
- 左侧放置仅当右侧不可用时
-
特殊情况处理:
- 纯间隔字符串(无M)返回0
- 单个M且无相邻间隔返回-1
- 连续三个M返回-1(中间M无相邻间隔)
代码实现
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);String cabinets = scanner.nextLine();System.out.println(minPowerBoxes(cabinets));}public static int minPowerBoxes(String cabinets) {// 字符串转字符数组便于处理char[] chars = cabinets.toCharArray();int n = chars.length;// 纯间隔情况if (!cabinets.contains("M")) {return 0;}// 检查开头和结尾的机柜是否可能被覆盖if (chars[0] == 'M' && (n == 1 || chars[1] != 'I')) {return -1;}if (chars[n-1] == 'M' && (n == 1 || chars[n-2] != 'I')) {return -1;}// 检查三个连续M的情况for (int i = 1; i < n-1; i++) {if (chars[i] == 'M' && chars[i-1] == 'M' && chars[i+1] == 'M') {return -1;}}boolean[] used = new boolean[n]; // 记录电箱位置int count = 0; // 电箱计数器for (int i = 0; i < n; i++) {if (chars[i] != 'M') continue; // 只处理机柜// 检查是否已被左侧电箱覆盖if (i > 0 && chars[i-1] == 'I' && used[i-1]) {continue;}// 优先尝试在右侧放置电箱if (i < n-1 && chars[i+1] ==