华为OD机试_2025_查找单入口空闲区域(Python,100分)(附详细解题思路)

题目描述

给定一个 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。

用例

|----|-------------------------------------|
| 输入 | 4 4 X X X X X O O X X O O X X O X X |
| 输出 | 3 1 5 |
| 说明 | 存在最大单入口区域,入口坐标(3,1),区域大小5 |

|----|---------------------------------------------|
| 输入 | 4 5 X X X X X O O O O X X O O O X X O X X O |
| 输出 | 3 4 1 |
| 说明 | 存在最大单入口区域,入口坐标(3,4),区域大小1 |

|----|---------------------------------------------|
| 输入 | 5 4 X X X X X O O O X O O O X O O X X X X X |
| 输出 | NULL |
| 说明 | 不存在最大单入口区域 |

|----|---------------------------------------------|
| 输入 | 5 4 X X X X X O O O X X X X X O O O X X X X |
| 输出 | 3 |
| 说明 | 存在两个大小为3的最大单入口区域,两个入口坐标分别为(1,3)、(3,3) |

最大单入口空闲区域问题详解

一、核心解题思路

问题分析

题目要求在给定的矩阵中找出最大的单入口空闲区域:

  1. 空闲区域由连续的'O'构成
  2. 单入口区域要求有且只有一个位于边界的'O'(矩阵边缘)
  3. 输出要求:
  • 唯一最大区域:输出入口坐标和区域大小
  • 多个相同大小的最大区域:只输出区域大小
  • 没有满足条件的区域:输出"NULL"

关键策略

  1. 连通区域检测:使用BFS/DFS遍历所有相邻的'O'
  2. 边界点统计:在遍历时标记位于边界的'O'
  3. 单入口判断:区域只有一个边界点才是单入口区域
  4. 结果筛选:找出最大区域,处理多个相同大小的情况

算法流程

复制代码
1. 遍历矩阵中的每个'O'点
2. 对未访问的'O'进行BFS/DFS:
- 统计区域大小
- 记录所有边界点坐标
3. 判断边界点数量是否为1:
- 是:记录(区域大小, 边界点坐标)
4. 结果处理:
- 没有单入口区域:输出"NULL"
- 唯一最大区域:输出入口坐标和大小
- 多个相同大小区域:输出区域大小
二、完整代码实现
python 复制代码
from collections import deque

def main():
import sys
data = sys.stdin.read().splitlines()
m, n = map(int, data[0].split())
matrix = []
for i in range(1, 1 + m):
matrix.append(data[i].split())

visited = [[False] * n for _ in range(m)]
directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]
regions = []# 存储单入口区域信息:(size, entrance_x, entrance_y)

for i in range(m):
for j in range(n):
if matrix[i][j] == 'O' and not visited[i][j]:
queue = deque([(i, j)])
visited[i][j] = True
size = 0
boundary_points = []

while queue:
x, y = queue.popleft()
size += 1
# 检查是否为边界点
if x == 0 or x == m - 1 or y == 0 or y == n - 1:
boundary_points.append((x, y))

for dx, dy in directions:
nx, ny = x + dx, y + dy
if 0 <= nx < m and 0 <= ny < n and not visited[nx][ny] and matrix[nx][ny] == 'O':
visited[nx][ny] = True
queue.append((nx, ny))

# 如果是单入口区域
if len(boundary_points) == 1:
x0, y0 = boundary_points[0]
regions.append((size, x0, y0))

# 处理结果
if not regions:
print("NULL")
else:
# 按区域大小降序排序
regions.sort(key=lambda x: x[0], reverse=True)
max_size = regions[0][0]
max_regions = [r for r in regions if r[0] == max_size]

if len(max_regions) > 1:
print(max_size)
else:
size, x, y = max_regions[0]
print(f"{x} {y} {size}")

if __name__ == "__main__":
main()
三、示例解析

示例1:输入

复制代码
4 4
X X X X
X O O X
X O O X
X O X X

执行过程

  1. 检测到区域:包含5个'O'(坐标(1,1),(1,2),(2,1),(2,2),(3,1))
  2. 边界点:(3,1)(唯一)
  3. 记录:(size=5, x=3, y=1)
  4. 输出:3 1 5

图解

复制代码
(0,0) (0,1) (0,2) (0,3)XXXX
(1,0) (1,1) (1,2) (1,3)XOOX
(2,0) (2,1) (2,2) (2,3)XOOX
(3,0) (3,1) (3,2) (3,3)XOXX
边界点↑(红色)

示例2:输入

复制代码
4 5
X X X X X
O O O O X
X O O O X
X O X X O

执行过程

  1. 区域1(左下):7个'O',但有两个边界点(1,0)和(3,1) → 非单入口
  2. 区域2(右下):1个'O',边界点(3,4)(唯一)
  3. 记录:(size=1, x=3, y=4)
  4. 输出:3 4 1

示例3:输入

复制代码
5 4
X X X X
X O O O
X O O O
X O O X
X X X X

执行过程

  1. 检测到两个分离区域:
  • 区域1(第1行):3个'O',边界点(1,3)
  • 区域2(第3行):3个'O',边界点(3,3)
  1. 两个区域大小相同且都是单入口
  2. 输出:3
四、总结

关键要点

  • 边界点判断:检查坐标是否在矩阵边缘
  • 单入口条件:区域必须有且只有一个边界点
  • 结果筛选逻辑
  • 唯一最大区域 → 输出坐标和大小
  • 多个相同大小 → 输出大小
  • 无满足条件 → 输出"NULL"

注意事项

  1. 使用BFS/DFS遍历时注意边界检查
  2. 访问标记避免重复计算
  3. 区域大小比较使用降序排序
  4. 多个相同大小区域只输出大小值

此解法通过系统的区域检测和结果筛选,准确高效地解决了最大单入口空闲区域查找问题,完美符合题目要求。

相关推荐
极光代码工作室几秒前
基于NLP的论文关键词提取系统
python·深度学习·自然语言处理·nlp
海梨花2 分钟前
字节面试高频算法题
java·算法·面试·职场和发展
Wang ruoxi5 分钟前
Pygame 小游戏——数独
开发语言·python·pygame
吠品8 分钟前
处理 Python 类继承中那些变来变去的初始化参数
linux·前端·python
aqiu1111118 分钟前
python02
算法
瓦特what?9 分钟前
位运算核心技巧与应用
java·jvm·算法
无限码力9 分钟前
阿里算法岗 0530笔试真题 - 荆棘林的最优砍断计划
算法·阿里笔试真题·阿里机试真题·阿里算法岗笔试真题·阿里巴巴笔试真题
会Tk矩阵群控的小木11 分钟前
小红书矩阵软件:基于Python+ADB的多设备批量管理自动化脚本实战
运维·python·adb·矩阵·自动化·新媒体运营·个人开发
随意起个昵称11 分钟前
线性dp-LIS题目5(导弹拦截,二分优化)
c++·算法·动态规划
winlife_12 分钟前
全程用 AI 做一款商业级手游 · EP10 道具系统:让三个按钮真正改变棋盘
windows·算法·unity·ai编程·游戏开发·mcp·玩法系统