华为OD机试真题——最大相连男生数学生方阵(2025A卷:200分)Java/python/JavaScript/C/C++/GO最佳实现

2025 A卷 200分 题型

本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式;
并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析;
本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分享》

华为OD机试真题《最大相连男生数学生方阵》:


文章快捷目录

题目描述及说明

Java

python

JavaScript

C

GO


题目名称:最大相连男生数学生方阵


  1. 知识点:矩阵遍历、动态规划/DFS
  2. 时间限制:1秒
  3. 空间限制:256MB
  4. 限定语言:不限

题目描述

学校组织活动,将学生排成一个矩形方阵。请在矩形方阵中找到最大的位置相连的男生数量。这个相连位置在一个直线上,方向可以是水平的、垂直的、成对角线的或者呈反对角线的。
:学生个数不会超过10000。

输入描述

输入的第一行为矩阵的行数和列数,接下来的n行为矩阵元素,元素间用“,”分隔。

输出描述

输出一个整数,表示矩阵中最长的位置相连的男生个数。

示例

输入

3,4  
F,M,M,F  
F,M,M,F  
F,F,F,M  

输出

3  

说明:对角线方向存在连续3个男生(M),为最长连续线段。


Java

问题分析

我们需要在给定的学生矩阵中找到最长的连续男生(‘M’)线段,方向可以是水平、垂直、主对角线(左上到右下)或反对角线(右上到左下)。我们需要遍历所有可能的方向,计算每个方向上的最长连续’M’的长度,取最大值。

解题思路

  1. 输入解析:读取矩阵的行数和列数,然后读取矩阵数据。
  2. 遍历四个方向
    • 水平方向:逐行遍历,统计每行的连续’M’。
    • 垂直方向:逐列遍历,统计每列的连续’M’。
    • 主对角线:从第一行和第一列的每个点出发,沿右下方向遍历。
    • 反对角线:从第一行最后一列和最后一列的每个点出发,沿左下方向遍历。
  3. 动态更新最大值:在遍历过程中,实时更新最长连续’M’的长度。

代码实现

import java.util.Scanner;

public class Main {
   
    public static void main(String[] args) {
   
        Scanner scanner = new Scanner(System.in);
        
        // 读取行数和列数
        String[] firstLine = scanner.nextLine().split(",");
        int rows = Integer.parseInt(firstLine[0]);
        int cols = Integer.parseInt(firstLine[1]);
        
        // 读取矩阵数据
        char[][] matrix = new char[rows][cols];
        for (int i = 0; i < rows; i++) {
   
            String line = scanner.nextLine();
            String[] elements = line.split(",");
            for (int j = 0; j < cols; j++) {
   
                matrix[i][j] = elements[j].charAt(0);
            }
        }
        
        int max = 0; // 记录最大连续长度
        
        // 处理水平方向
        for (int i = 0; i < rows; i++) {
   
            int current = 0;
            for (int j = 0; j < cols; j++) {
   
                if (matrix[i][j] == 'M') {
   
                    current++;
                    max = Math.max(max, current);
                } else {
   
                    current = 0;
                }
            }
        }
        
        // 处理垂直方向
        for (int j = 0; j < cols; j++) {
   
            int current = 0;
            for (int i = 0; i < rows; i++) {
   
                if (matrix[i][j] == 'M') {
   
                    current++;
                    max = Math.max(max, current);
                } else {
   
                    current = 0;
                }
            }
        }
        
        // 处理主对角线方向(右下)
        // 第一行的每个列作为起点
        for (int j = 0; j < cols; j++) {
   
            int x = 0, y = j;
            int current = 0;
            while (x < rows && y < cols) {
   
                if (matrix[x][y] == 'M') {
   
                    current++;
                    max = Math.max(max, current);
                } else {
   
                    current = 0;
                }
                x++;
                y++;
            }
        }
        // 第一列的每个行(除第一个)作为起点
        for (int i = 1; i < rows; i++) {
   
            int x = i, y = 0;
            int current = 0;
            while (x < rows && y < cols) {
   
                if (matrix[x][y] == 'M') {
   
                    current++;
                    max = Math.max(max, current);
                } else {
   
                    current = 0;
                }
                x++;
                y++;
            }
        }
        
        // 处理反对角线方向(左下)
        // 第一行的每个列作为起点
        for (int j = 0; j < cols; j++) {
   
            int x = 0, y = j;
            int current = 0;
            while (x < rows && y >= 0) {
   
                if (matrix[x][y] == 'M') {
   
                    current++;
                    max = Math.max(max, current);
                } else {
   
                    current = 0;
                }
                x++;
                y--;
            }
        }
        // 最后一列的每个行(除第一个)作为起点
        for (int i = 1; i < rows; i++) {
   
            int x = i, y = cols - 1;
            int current = 0;
            while (x < rows && y >= 0) {
   
                if (matrix[x][y] == 'M') {
   
                    current++;
                    max = Math.max(max, current);
                } else {
   
                    current = 0;
                }
                x++;
                y--;
            }
        }
        
        System.out.println(max);
    }
}

代码详解

  1. 输入解析:读取矩阵的行数和列数,并逐行读取矩阵数据,存储在二维字符数组matrix中。
  2. 水平方向处理:遍历每一行,统计每行的连续’M’长度,遇到’F’时重置计数器。
  3. 垂直方向处理:遍历每一列,统计每列的连续’M’长度,遇到’F’时重置计数器。
  4. 主对角线处理
    • 从第一行的每个点出发,沿右下方向遍历。
    • 从第一列的每个点(除第一行)出发,沿右下方向遍历。
  5. 反对角线处理
    • 从第一行的每个点出发,沿左下方向遍历。
    • 从最后一列的每个点(除第一行)出发,沿左下方向遍历。
  6. 动态更新最大值:在每次遍历过程中,实时更新最大连续’M’的长度。

示例测试

示例1
输入:

3,4
F,M,M,F
F,M,M,F
F,F,F,M

输出:3
解析:对角线方向存在三个连续的’M’。

示例2
输入:

4,4
M,M,M,M
F,F,F,F
M,M,M,M
F,F,F,F

输出:4
解析:水平方向每行有四个连续的’M’。

示例3
输入:

2,2
M,M
M,M

输出:2
解析:四个方向上的连续’M’长度均为2。

综合分析

  1. 时间复杂度:每个方向的时间复杂度为O(nm),总时间复杂度为O(nm),适用于矩阵规模较小的场景。
  2. 空间复杂度:仅使用输入矩阵的存储空间,空间复杂度为O(nm)。
  3. 最优性:遍历所有可能的方向,确保找到全局最优解。
  4. 适用性:适用于题目给定的数据规模(学生数不超过10000),能高效处理所有可能的情况。

python

问题分析

我们需要在给定的学生矩阵中找到最长的连续男生(‘M’)线段,方向可以是水平、垂直、主对角线(左上到右下)或反对角线(右上到左下)。目标是遍历所有方向,找到最长连续’M’的长度。


解题思路

  1. 输入解析:读取矩阵的行列数,并将学生数据转换为二维列表。
  2. 遍历四个方向
    • 水平方向:逐行遍历,统计每行的连续’M’。
    • 垂直方向:逐列遍历,统计每列的连续’M’。
    • 主对角线:从第一行和第一列出发,沿右下方向遍历。
    • 反对角线:从第一行和最后一列出发,沿左下方向遍历。
  3. 动态更新最大值:在遍历过程中实时更新最长连续’M’的长度。

代码实现

def main():
    import sys
    # 读取输入
    lines = [line.strip() for line in sys.stdin if line.strip()]
    rows, cols = map(int, lines[0].split(','))
    matrix = []
    for line in lines[1:rows+1]:
        matrix.append(line.split(','))
    
    max_len = 0  # 记录最大连续长度
    
    # 处理水平方向
    for i in range(rows):
        current = 0
        for j in range(cols):
            if matrix[i][j] == 'M':
                current += 1
                max_len = max(max_len, current)
            else:
                current = 0
    
    # 处理垂直方向
    for j in range(cols):
        current = 0
        for i in 

你可能感兴趣的:(华为OD,华为od,java,python,javascript,c语言,c++)