华为OD机试真题 Java 实现【查找单入口空闲区域】【2022 Q4 100分】,附详细解题思路

news2024/12/24 10:31:15

在这里插入图片描述

目录

    • 一、题目描述
    • 二、输入描述
    • 三、输出描述
    • 四、解题思路
    • 五、Java算法源码
    • 六、效果展示
      • 1、输入
      • 2、输出
      • 3、说明

一、题目描述

给定一个 m x n 的矩阵,由若干字符 ‘X’ 和 ‘O’构成,’X’表示该处已被占据,’O’表示该处空闲,请找到最大的单入口空闲区域。

解释:

空闲区域是由连通的’O’组成的区域,位于边界的’O’可以构成入口,

单入口空闲区域即有且只有一个位于边界的’O’作为入口的由连通的’O’组成的区域。

如果两个元素在水平或垂直方向相邻,则称它们是“连通”的。

二、输入描述

第一行输入为两个数字,第一个数字为行数m,第二个数字为列数n,两个数字以空格分隔,1<=m,n<=200。

剩余各行为矩阵各行元素,元素为‘X’或‘O’,各元素间以空格分隔。

三、输出描述

若有唯一符合要求的最大单入口空闲区域,输出三个数字

第一个数字为入口行坐标(0~m-1)
第二个数字为入口列坐标(0~n-1)
第三个数字为区域大小
三个数字以空格分隔;

若有多个符合要求,则输出区域大小最大的,若多个符合要求的单入口区域的区域大小相同,则此时只需要输出区域大小,不需要输出入口坐标。

若没有,输出NULL。

四、解题思路

这道题我们需要找到最大的单入口空闲区域。因此,我们需要遍历矩阵,找到所有位于边界的 0,然后计算以这些 0 为入口的最大空闲区域的大小。最后,找到最大的空闲区域即可。

对于每个入口,我们可以使用 DFS 算法遍历矩阵,计算以当前入口为起点的空闲区域的大小。在遍历过程中,我们需要标记已经访问过的位置,避免重复计算。同时,如果当前位置不是边界位置,我们需要确保它不是入口,否则,我们会重复计算已经计算过的区域。

五、Java算法源码

package com.nezha.od;

import java.util.*;

public class OdTest {
    static int rows;
    static int cols;
    // 存储区域
    static List<List<String>> board;
    // 上下左右四个方向
    static List<List<Integer>> directions = Arrays.asList(
            Arrays.asList(0, -1),
            Arrays.asList(0, 1),
            Arrays.asList(-1, 0),
            Arrays.asList(1, 0));
    // 存储已经访问过的格子的坐标
    static Set<String> visited = new HashSet<>();

    // dfs函数返回连通块中的格子数量,同时将连通块的边界坐标存入enter中
    static int dfs(int row, int col, int count, List<List<Integer>> enter) {
        // 将坐标转化为字符串,方便存储到visited中
        String pos = row + "-" + col;

        // 如果当前格子不在区域内,或者是障碍物,或者已经访问过,直接返回当前连通块的格子数量
        if (row < 0 || row >= rows || col < 0 || col >= cols || board.get(row).get(col).equals("X") || visited.contains(pos)) {
            return count;
        }

        // 将当前格子标记为已访问
        visited.add(pos);

        // 如果当前格子在区域的边界上,将其坐标存入enter中
        if (row == 0 || row == rows - 1 || col == 0 || col == cols - 1) {
            enter.add(Arrays.asList(row, col));
        }

        count++; // 当前连通块的格子数量加1

        // 对当前格子的四个方向进行dfs搜索
        for (List<Integer> dir : directions) {
            int newRow = row + dir.get(0);
            int newCol = col + dir.get(1);
            count = dfs(newRow, newCol, count, enter);
        }

        return count;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        rows = sc.nextInt();
        cols = sc.nextInt();

        board = new ArrayList<>();
        for (int i = 0; i < rows; i++) {
            List<String> row = new ArrayList<>();
            for (int j = 0; j < cols; j++) {
                row.add(sc.next());
            }
            board.add(row);
        }

        // 存储所有符合条件的连通块
        List<List<Integer>> ans = new ArrayList<>();

        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                // 如果当前格子是未访问过的O格子,进行dfs搜索
                if (board.get(i).get(j).equals("O") && !visited.contains(i + "-" + j)) {
                    List<List<Integer>> enter = new ArrayList<>();
                    // 计算当前连通块的格子数量和边界坐标
                    int count = dfs(i, j, 0, enter);
                    // 如果当前连通块只有一个边界,将其存入ans中
                    if (enter.size() == 1) {
                        List<Integer> pos = enter.get(0);
                        List<Integer> an = Arrays.asList(pos.get(0), pos.get(1), count);
                        ans.add(an);
                    }
                }
            }
        }

        // 如果没有符合条件的连通块,输出NULL
        if (ans.size() == 0) {
            System.out.println("NULL");
        } else {
            // 对符合条件的连通块按照格子数量从大到小排序
            ans.sort((a, b) -> b.get(2) - a.get(2));

            // 如果最大的连通块是唯一的,输出其边界坐标和格子数量;否则,只输出最大的连通块的格子数量
            if (ans.size() == 1 || ans.get(0).get(2) > ans.get(1).get(2)) {
                String res = "";
                for (int ele : ans.get(0)) {
                    res += ele + " ";
                }
                System.out.println(res);
            } else {
                System.out.println(ans.get(0).get(2));
            }
        }
    }
}

六、效果展示

1、输入

5 4
X X X X
X O O O
X X X X
X O O O
X X X X

2、输出

3

3、说明

存在两个大小为3的最大单入口区域,两个入口坐标分别为(1,3)、(3,3)。

在这里插入图片描述


🏆下一篇:华为OD机试真题 Java 实现【跳房子II】【2023 B卷 100分】,附详细解题思路

🏆本文收录于,华为OD机试(JAVA)(2022&2023)

刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,订阅后,专栏内的文章都可看,可加入华为OD刷题群(私信即可),发现新题目,随时更新,全天CSDN在线答疑。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/713591.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JS】将表格数据下载为 .csv 文件

文章目录 代码实现 代码实现 1. 将表格数据转换为字符串格式 2. 字符串格式里面的,逗号表示换列 3. 字符串格式里面的\n符号表示换行实现 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title></head><…

Linux(包括centos) 如何查看服务器内存、CPU

CPU架构 CPU架构主要包括&#xff1a;amd64、arm32v7、arm64v8、mips64el、mips32、ppc64le和ppc32等架构。 CPU信息 CPU信息主要为中央处理器详细信息&#xff0c;包括&#xff1a; 架构核心数量处理速度厂商名称CPU主频标签 … 注&#xff1a;不同的操作系统或者CPU架构提供…

怎么提取视频中的音频?这些提取音频方法很简单

将视频中的音频提取出来&#xff0c;可以单独对音频进行处理&#xff0c;如剪辑、增强声音等&#xff0c;而不影响视频本身的内容。在后期制作中&#xff0c;音频需要经过一系列的处理&#xff0c;如去噪、降噪、混响等&#xff0c;提取出音频可以更方便地进行这些处理&#xf…

MHA高可用

文章目录 MHA高可用1 定义2 组成3 特点4 搭建MySQL MHA4.1 配置主从复制4.2 关闭防火墙&#xff0c;安全机制4.3 修改Master、Slave1、Slave2节点的主机名4.4 添加主机映射关系4.5 修改 Master、Slave1、Slave2 节点的 Mysql主配置文件/etc/my.cnf4.6 在master、slave1、slave2…

2023年--上半年小程序团队工作总结

前言 大家好&#xff0c;这是小程序团队第一次跟大家见面。小程序团队从2020年开始&#xff0c;就着手进行着小程序的开发。 在2020年7月上线了第一个现在仍在使用的上古小程序&#xff1a;课程小程序 和 我的内容库小程序。 小伙伴们可能还不知道&#xff0c;你们平时日常在cs…

10分钟看透微信公众号支付

开发痛点 如何配置微信&#xff1f;怎么个流程&#xff1f;怎么入手&#xff1f;如何本地调试&#xff1f;网上教程10个小时不想看怎么办&#xff1f;这里一篇文章带你入手微信支付。看看微信公众号支付到底有什么神奇之处。 开发后结果 微信配置 1、首先打开文档中心&#…

dy系点选验证码协议2023/07/3 一直可用

前言 可以关注我哟,一起学习,主页有更多练习例子 如果哪个练习我没有写清楚,可以留言我会补充 如果有加密的网站可以留言发给我,一起学习共享学习路程 如侵权,联系我删除 此文仅用于学习交流,请勿于商用,否则后果自负 因为需求不得不搞,小白一个,哪有不对,大佬多多…

Linux 学习记录44(C++篇)

Linux 学习记录44(C篇) 本文目录 Linux 学习记录44(C篇)一、静态成员变量/函数1. 静态成员变量2. 静态成员函数 二、继承1. 继承的作用2. 继承的格式3. 子类对父类中成员的继承4. 子类中存在和父类同名成员时5. 继承中特殊的成员函数(1. 构造函数(2. 析构函数(3. 拷贝构造函数(…

OpenAI遭集体诉讼!窃取数百万用户信息?明星大模型变“数据小偷”!

“尽管制定了购买和使用个人信息的协议&#xff0c;但被告采取了不同的方法&#xff1a;窃取。”近日&#xff0c;一家律师事务所用一份长达157页的诉讼将OpenAI告到法庭&#xff0c;指控其在利润的驱使下&#xff0c;窃取大量个人信息来训练人工智能模型。 起诉书称&#xff0…

UE4 TCP通信 (UE作为客户端接收字节)

在上一篇(UE4 TCP通信)基础上,实现UE客户端接收服务端推送的字节数据并解析。 效果 (注意看左上角的打印信息) 步骤 1. 首先新建一个工程,然后创建一个Actor蓝图,这里命名为“BP_TCPConnect” 打开“BP_TCPConnect”,添加如下节点: (1)当服务端与客户端断开连接时…

SpringBoot+Vue+Element-ui实现简单登录注册功能

目录 1.前端 &#xff08;1&#xff09;登录和注册页面 HomeView.vue RegisterView.vue &#xff08;2&#xff09; main.js&#xff0c;作请求和响应拦截 2.后端 &#xff08;1&#xff09;mapper.xml &#xff08;2&#xff09;mapper接口 &#xff08;3&#xff0…

六本入选!首批“十四五”职业教育国家规划教材书目

近日&#xff0c;教育部办公厅公布了首批“十四五”职业教育国家规划教材书目&#xff0c;其中广东泰迪智能科技股份有限公司携手院校联合编写的6本教材入选该名单。 入选首批“十四五” 职业教育国家规划教材介绍 高职“十四五”职业教育国家规划教材 Python编程基础(第2版)…

平时成绩综合评价与总成绩预测模型

已排除非本人创作部分 摘要 针对问题一&#xff0c;我们首先对所有团队的数据做了正态性检验&#xff0c;共x次作业&#xff0c;每次作业成绩分布均可用正态分布描述。其次&#xff0c;我们对团队之间的成绩变化做了格兰杰因果检验&#xff0c;列出了成绩变化相关的一部分团队…

STL补充:STL中遵循的左闭右开原则/STL随机访问

文章目录 左闭右开原则示例&#xff1a;示例中erase的用法不能写成s.erase(s.begin()left)的原因 STL中支持随机访问的迭代器 左闭右开原则 在 C 中&#xff0c;容器&#xff08;如 vector&#xff0c;set&#xff0c;map 等&#xff09;的迭代器都遵循左闭右开的原则。 也就…

微服务- Eureka 注册

1. 首先从结构方面来说 单体架构&#xff1a;比较适合用于小型项目&#xff08;像一些学生管理系统&#xff09;&#xff0c;简单方便&#xff0c;高度耦合 分布式架构&#xff1a;松耦合&#xff0c;扩展性好&#xff0c;但架构复杂&#xff0c;难度大&#xff0c;适合大型互联…

CIO40---3个亿数字化供应链实战

2019年某天&#xff0c;我被总裁叫到办公室&#xff0c;我当是VP A&#xff1a;企业情况 一家A股上市 市值150亿&#xff0c;年销售50亿&#xff0c; 员工4000人&#xff0c;全国4个工厂 家庭企业&#xff0c;高管老人多 经销商模式&#xff0c;总代模式&#xff0c;工程…

unserialize3

看着这个源码长度&#xff0c;就觉着比较简单 本题就一个__wakeup方法需要绕过&#xff0c;但是不对哦没有提示也不知道该参数得多少呀 本来都要复制进编译器写了&#xff0c;发现源码闭合有点问题&#xff0c;可能是做了隐藏 解题步骤 实在找不到了&#xff0c;就尝试了一下fl…

81、基于STM32单片机的颜色识别 TCS3200 RGB 检测系统设计(程序+原理图+PCB源文件+参考论文+开题报告+任务书+设计资料+元器件清单等)

摘 要 随着现代工业生产向高速化、自动化方向的发展&#xff0c;色彩识别广泛应用于各种工业检测和自动控制领域&#xff0c;而生产过程中长期以来由人眼起主导作用的颜色识别工作将越来越多地被相应的颜色传感器所替代。如&#xff1a;各种物体表面颜色识别&#xff08;产品包…

什么是三极管推挽电路

这是一个三极管推挽电路&#xff0c;上面是一个NPN的三极管&#xff0c;下面是一个PNP的三极管。 当输入信号为VCC时&#xff0c;上面的三极管导通&#xff0c;下面的三极管截止&#xff0c;输出信号为VCC-0.7V&#xff0c;这个0.7V就是上面NPN三极管BE间的导通压降 当输入信号…

Spring Bean 作用域的定义

在 Spring 配置中&#xff0c;我们可以通过 scope 属性来定义 Spring Bean 的作用域&#xff0c;可以接受 5 个内建的值&#xff0c;分别代表 5 种作用域类型&#xff0c;下面给大家详细总结一下&#xff1a; 1、singleton&#xff0c;用来定义一个 Bean 为单例&#xff0c;也…