2024华为OD试题及答案-A005-查找单入口空闲区域

题目描述

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

问题解析

题目要求找到一个矩阵中由'O'组成的最大单入口空闲区域。矩阵中的'X'表示该处被占据,'O'表示该处为空闲。单入口空闲区域即为且只有一个位于边界的'O'作为入口的由连通的'O'组成的区域。如果两个元素在水平或垂直方向相邻,则称它们是“连通”的。

步骤分析:

  1. 输入处理

    • 第一行输入两个整数 m 和 n,表示矩阵的行数和列数。
    • 接下来的 m 行,每行输入一个字符串,表示矩阵中的元素,元素为'X'或'O'。
  2. 寻找单入口空闲区域

    • 遍历矩阵边界,寻找边界上的'O'。
    • 对每个边界上的'O',使用深度优先搜索(DFS)或者广度优先搜索(BFS)来标记所有连通的'O'。
    • 确定每个区域是否为单入口,并记录区域大小。
  3. 输出结果

    • 输出符合条件的最大单入口空闲区域的行坐标、列坐标和区域大小。
    • 如果没有符合条件的区域,输出 "NULL"。

代码实现

以下是实现该逻辑的C++代码:

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

struct Position {
    int x, y;
};

vector<vector<char>> matrix;
vector<vector<bool>> visited;
int m, n;

int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};

bool isValid(int x, int y) {
    return (x >= 0 && x < m && y >= 0 && y < n && matrix[x][y] == 'O' && !visited[x][y]);
}

int bfs(int startX, int startY) {
    queue<Position> q;
    q.push({startX, startY});
    visited[startX][startY] = true;

    int areaSize = 0;
    int entranceCount = 0;

    while (!q.empty()) {
        Position curr = q.front();
        q.pop();
        areaSize++;

        for (int i = 0; i < 4; ++i) {
            int newX = curr.x + dx[i];
            int newY = curr.y + dy[i];

            if (isValid(newX, newY)) {
                visited[newX][newY] = true;
                q.push({newX, newY});
            } else if (newX < 0 || newX >= m || newY < 0 || newY >= n) {
                entranceCount++;
            }
        }
    }

    return (entranceCount == 1) ? areaSize : -1;
}

int main() {
    cin >> m >> n;
    matrix.resize(m, vector<char>(n));
    visited.resize(m, vector<bool>(n, false));

    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
            cin >> matrix[i][j];
        }
    }

    int maxAreaSize = 0;
    int entranceX = -1, entranceY = -1;

    for (int i = 0; i < m; ++i) {
        if (matrix[i][0] == 'O' && !visited[i][0]) {
            int areaSize = bfs(i, 0);
            if (areaSize > maxAreaSize) {
                maxAreaSize = areaSize;
                entranceX = i;
                entranceY = 0;
            }
        }
        if (matrix[i][n - 1] == 'O' && !visited[i][n - 1]) {
            int areaSize = bfs(i, n - 1);
            if (areaSize > maxAreaSize) {
                maxAreaSize = areaSize;
                entranceX = i;
                entranceY = n - 1;
            }
        }
    }

    for (int j = 0; j < n; ++j) {
        if (matrix[0][j] == 'O' && !visited[0][j]) {
            int areaSize = bfs(0, j);
            if (areaSize > maxAreaSize) {
                maxAreaSize = areaSize;
                entranceX = 0;
                entranceY = j;
            }
        }
        if (matrix[m - 1][j] == 'O' && !visited[m - 1][j]) {
            int areaSize = bfs(m - 1, j);
            if (areaSize > maxAreaSize) {
                maxAreaSize = areaSize;
                entranceX = m - 1;
                entranceY = j;
            }
        }
    }

    if (maxAreaSize > 0) {
        cout << entranceX << " " << entranceY << " " << maxAreaSize << endl;
    } else {
        cout << "NULL" << endl;
    }

    return 0;
}

代码说明:

  1. 数据结构:使用二维字符矩阵表示输入的区域,使用二维布尔矩阵表示访问状态。
  2. 辅助函数isValid 用于检查位置是否有效并且未被访问,bfs 用于广度优先搜索计算区域大小。
  3. 主函数
    • 读取矩阵尺寸和矩阵元素。
    • 遍历矩阵边界,找到边界上的'O'并进行广度优先搜索。
    • 输出最大的单入口空闲区域,如果不存在则输出 "NULL"。

输入输出示例:

  • 输入:
4 4
X O O X
O X O O
X O X X
O O X X
  • 输出:
1 0 3

该程序能够根据输入的矩阵正确找到并输出最大的单入口空闲区域的相关信息。

Python 实现

def is_valid(x, y, m, n, matrix, visited):
    return 0 <= x < m and 0 <= y < n and matrix[x][y] == 'O' and not visited[x][y]

def bfs(start_x, start_y, m, n, matrix, visited):
    queue = [(start_x, start_y)]
    visited[start_x][start_y] = True
    area_size = 0
    entrance_count = 0

    dx = [0, 0, 1, -1]
    dy = [1, -1, 0, 0]

    while queue:
        curr_x, curr_y = queue.pop(0)
        area_size += 1

        for i in range(4):
            new_x = curr_x + dx[i]
            new_y = curr_y + dy[i]

            if is_valid(new_x, new_y, m, n, matrix, visited):
                visited[new_x][new_y] = True
                queue.append((new_x, new_y))
            elif new_x < 0 or new_x >= m or new_y < 0 or new_y >= n:
                entrance_count += 1

    return area_size if entrance_count == 1 else -1

def main():
    m, n = map(int, input().split())
    matrix = [input().split() for _ in range(m)]
    visited = [[False] * n for _ in range(m)]

    max_area_size = 0
    entrance_x = -1
    entrance_y = -1

    for i in range(m):
        if matrix[i][0] == 'O' and not visited[i][0]:
            area_size = bfs(i, 0, m, n, matrix, visited)
            if area_size > max_area_size:
                max_area_size = area_size
                entrance_x = i
                entrance_y = 0
        if matrix[i][n - 1] == 'O' and not visited[i][n - 1]:
            area_size = bfs(i, n - 1, m, n, matrix, visited)
            if area_size > max_area_size:
                max_area_size = area_size
                entrance_x = i
                entrance_y = n - 1

    for j in range(n):
        if matrix[0][j] == 'O' and not visited[0][j]:
            area_size = bfs(0, j, m, n, matrix, visited)
            if area_size > max_area_size:
                max_area_size = area_size
                entrance_x = 0
                entrance_y = j
        if matrix[m - 1][j] == 'O' and not visited[m - 1][j]:
            area_size = bfs(m - 1, j, m, n, matrix, visited)
            if area_size > max_area_size:
                max_area_size = area_size
                entrance_x = m - 1
                entrance_y = j

    if max_area_size > 0:
        print(entrance_x, entrance_y, max_area_size)
    else:
        print("NULL")

if __name__ == "__main__":
    main()

代码说明:

  1. is_valid函数:检查位置是否有效且未被访问。
  2. bfs函数:进行广度优先搜索,计算区域大小。
  3. main函数
    • 读取矩阵尺寸和矩阵元素。
    • 遍历矩阵边界,找到边界上的'O'并进行广度优先搜索。
    • 输出最大的单入口空闲区域,如果不存在则输出 "NULL"。

使用示例:

运行程序时,将按照下述步骤操作:

  1. 输入矩阵的行数和列数。
  2. 输入矩阵的各行,元素为'X'或'O',各元素间以空格分隔。
  3. 程序将输出符合条件的最大单入口空闲区域的行坐标、列坐标和区域大小。如果没有符合条件的区域,输出 "NULL"。

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值