当前位置: 首页 > article >正文

查找单入口空闲区域[A卷-hw_od]

查找单入口空闲区域[A卷 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。

用例1

输入:

4 4
X X X X
X O O X
X O O X
X O X X

输出: 

 3 1 5

说明: 

存在最大单入口区域,入口坐标(3,1),区域大小5

用例2

输入:

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

用例3

输入

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

 

输出

NULL

说明

不存在最大单入口区域

用例4

输入

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)

#include <bits/stdc++.h>
using namespace std;
struct Region {
    int ex, ey, size;
};
int m, n;
vector<vector<char>> grid;
vector<vector<bool>> visited;
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
int region_size;
int ex, ey;
int border_count;
void dfs(int x, int y) {
    visited[x][y] = true;
    region_size++;
    
    if (x == 0 || x == m-1 || y == 0 || y == n-1) {
        border_count++;
        ex = x;
        ey = y;
    }
    
    for (int i = 0; i < 4; i++) {
        int nx = x + dx[i], ny = y + dy[i];
        if (nx >= 0 && nx < m && ny >= 0 && ny < n && grid[nx][ny] == 'O' && !visited[nx][ny]) {
            dfs(nx, ny);
        }
    }
}
int main() {
    cin >> m >> n;
    grid.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 >> grid[i][j];
        }
    }
    
    vector<Region> regions;
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            if ((i == 0 || i == m-1 || j == 0 || j == n-1) && grid[i][j] == 'O' && !visited[i][j]) {
                region_size = 0;   //区域大小计数
                border_count = 0;  //边界计数
                ex = i;
                ey = j;
                
                dfs(i, j);
                
                if (border_count == 1) {
                    regions.push_back({ex, ey, region_size}); //符合条件1
                }
            }
        }
    }
    
    if (regions.empty()) {
        cout << "NULL" << endl;
        return 0;
    }
    
    int max_size = 0;
    for (const auto &r : regions) max_size = max(max_size, r.size);
    
    vector<Region> largest;
    for (const auto &r : regions) {
        if (r.size == max_size) largest.push_back(r);
    }
    
    if (largest.size() == 1) {
        cout << largest[0].ex << " " << largest[0].ey << " " << largest[0].size << endl;
    } else {
        cout << max_size << endl;
    }
    
    return 0;
}

思路:就是深搜,按题意进行模拟(符合条件1:开口只有一个的最大面积 -> 输出坐标和面积大小 2:多个符合条件1, 只需输出面积大小 3. 一个没有直接cout<<NULL), 但是要注意边界 

另一个思路就是BFS(不建议,直接所有题全部用递归(dfs),能够加深你对递归这个反人类思考方式的理解) 

 

 


http://www.kler.cn/a/598873.html

相关文章:

  • JS Typeof 运算符
  • 系统设计类问题回答模板
  • SQL Server行转列操作及PIVOT运算符
  • 算法基础篇(1)(蓝桥杯常考点)
  • FPGA时钟约束
  • 基于Matlab实现语音识别算法(源码+数据)
  • 【Linux文件IO】通过文件IO把bmp图片显示到Linux开发板的实现
  • 基于springboot的新闻推荐系统(045)
  • 【NLP 42、实践 ⑪ 用Bert模型结构实现自回归语言模型的训练】
  • 人脸表情识别系统分享(基于深度学习+OpenCV+PyQt5)
  • Spring Boot框架中常用注解
  • 【mysql】同一个字段,字符串相加
  • 从Oracle到OceanBase数据库迁移:全方位技术解析
  • 如何让Go 的regexp包支持 (?!...) 这样的 Perl 语法?
  • PHP转GO Day3 函数定义与包管理实践(创建数学工具包)
  • 2.1.项目管理前言
  • 【Linux】:守护进程化
  • 【JavaEE】Mybatis基础使用注解 增删改查操作
  • DeepSeek政务应用场景与解决方案【清华大学最新版】
  • 996引擎-接口测试:背包