华为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. 多个相同大小区域只输出大小值

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

相关推荐
皮蛋sol周2 分钟前
嵌入式学习C语言(八)二维数组及排序算法
c语言·学习·算法·排序算法
李昊哲小课19 分钟前
销售数据可视化分析项目
python·信息可视化·数据分析·matplotlib·数据可视化·seaborn
森焱森26 分钟前
单片机中 main() 函数无 while 循环的后果及应对策略
c语言·单片机·算法·架构·无人机
烛阴29 分钟前
带参数的Python装饰器原来这么简单,5分钟彻底掌握!
前端·python
平和男人杨争争43 分钟前
机器学习12——支持向量机中
算法·机器学习·支持向量机
全干engineer1 小时前
Flask 入门教程:用 Python 快速搭建你的第一个 Web 应用
后端·python·flask·web
10岁的博客1 小时前
代码编程:一场思维与创造力的革命
开发语言·算法
nightunderblackcat1 小时前
新手向:Python网络编程,搭建简易HTTP服务器
网络·python·http
李昊哲小课1 小时前
pandas销售数据分析
人工智能·python·数据挖掘·数据分析·pandas
Aczone281 小时前
嵌入式 数据结构学习 (六) 树、哈希表与内核链表
数据结构·学习·算法