1. 问题背景与算法概述
这道题目来自信息学奥赛经典题库,要求计算由特定符号围成的闭合区域面积。题目给出的示例是一个10×10的二维矩阵,其中数字1代表边界符号"*",数字0代表空白区域。我们需要统计被1完全包围的0的个数,这个数量就是所求的面积。
Flood fill算法是解决这类连通区域问题的经典方法,它通过从某个起始点出发,遍历所有相连的同类区域。在图像处理中常用于油漆桶工具,在游戏开发中用于地图探索系统。本题的特殊之处在于需要处理"包围"的概念,即如何区分被包围的空白区域和外部空白区域。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 算法核心思路解析
2.1 边界扩展技巧
常规的Flood fill实现会面临一个关键问题:当多个边界点都需要作为起点时,如何高效处理?题目解析中提到的"扩展边界"技巧给出了优雅的解决方案:
- 将原始10×10矩阵扩展为12×12(四周各加一圈)
- 新增的外围边界全部初始化为0
- 从(0,0)这个虚拟起点开始单次BFS即可标记所有外部可达区域
这个技巧的价值在于:
- 将可能的多起点问题转化为单起点问题
- 确保所有外部连通区域都能被一次性标记
- 内部被包围的区域自然保持未标记状态
2.2 算法流程分解
-
预处理阶段:
- 读取10×10的输入矩阵
- 将其放置在12×12矩阵的中心位置(即行和列索引1-10)
- 外围扩展的行列(索引0和11)全部置0
-
填充阶段:
- 从(0,0)开始BFS遍历
- 将所有连通的外部0标记为特殊值(代码中使用7)
- 遇到1时停止该方向的扩散
-
统计阶段:
- 扫描原始10×10区域
- 统计未被标记(仍为0)的格子数量
- 这个数量就是所求的包围面积
3. 代码实现详解
3.1 数据结构设计
cpp复制typedef pair<int,int> PII; // 坐标点类型
const int N = 15; // 矩阵尺寸(10+2)
int mp[N][N]; // 扩展后的矩阵
int dx[] = {1,0,-1,0}; // 方向向量:下、右、上、左
int dy[] = {0,1,0
