题目描述
编程计算由"*"号围成的下列图形的面积。面积计算方法是统计*号所围成的闭合曲线中水平线和垂直线交点的数目。如下图所示,在10×10的二维数组中,有"*"围住了15个点,因此面积为15。
输入
10×10的图形。
输出
输出面积。
样例
输入数据 1
0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 1 1 0 0 0
0 0 0 0 1 0 0 1 0 0
0 0 0 0 0 1 0 0 1 0
0 0 1 0 0 0 1 0 1 0
0 1 0 1 0 1 0 0 1 0
0 1 0 0 1 1 0 1 1 0
0 0 1 0 0 0 0 1 0 0
0 0 0 1 1 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0
输出数据 1
15
来源
一本通在线评测
围成面积问题思路
问题分析:
计算由''字符围成的闭合区域面积,实际是统计被''包围的空白点数量。
核心思路:洪水填充法(Flood Fill)
从边界开始向外扩散,标记所有能够到达的空白点,剩下的未被标记的空白点就是被包围的区域。
具体步骤:
-
- 预处理:
- •将输入数据存储在10×10的字符矩阵中
- •在矩阵外围添加一圈空白(作为边界起点)
-
- 边界洪水填充:
- •从四个角点开始进行BFS/DFS遍历
- •将所有与边界连通的空白点标记为已访问
-
- 统计内部空白点:
- •遍历整个矩阵(不包括外围添加的边界)
- •统计未被标记的空白点数量(这些就是被'*'包围的区域)
-
- 输出结果:
- •内部空白点数量即为所求面积
算法选择:
- •BFS(广度优先搜索):更适合矩阵遍历,避免递归深度问题
- •方向处理:四个方向(上、下、左、右)移动
关键点:
- 1.外围扩展:在10×10矩阵外添加一圈,确保能从边界开始填充
- 2.标记机制:使用visited数组记录可达点
- 3.边界条件 :只处理空白点(非''字符),遇到''则停止扩散
复杂度分析:
- •时间复杂度:O(n²) = O(100)
- •空间复杂度:O(n²) = O(100)
示例验证:
对于样例输入,通过洪水填充后,内部未被标记的空白点正好是15个,与题目描述一致。
这种方法能够准确识别闭合区域,适用于各种形状的包围情况。
代码样例
cpp
#include<bits/stdc++.h>
using namespace std;
char mp[12][12];
bool vis[12][12];
int dx[]= {0,0,1,-1};
int dy[]= {1,-1,0,0};
void dfs(int x,int y)
{
if(x<0 || x>11 || y<0 || y>11)
{
return;
}
if(vis[x][y] || mp[x][y]=='1')
{
return;
}
vis[x][y]=1;
for(int i=0; i<4; i++)
{
dfs(x+dx[i],y+dy[i]);
}
}
int main()
{
for(int i=0; i<12; i++)
{
for(int j=0; j<12; j++)
{
mp[i][j]='0';
}
}
for(int i=1; i<=10; i++)
{
for(int j=1; j<=10; j++)
{
cin>>mp[i][j];
}
}
dfs(0,0);
int cnt=0;
for(int i=1; i<=10; i++)
{
for(int j=1; j<=10; j++)
{
if(!vis[i][j] && mp[i][j]=='0')
{
cnt++;
}
}
}
cout<<cnt;
return 0;
}
此代码仅供参考,请勿纯抄