闭合区域面积统计(area)
题目描述
编程计算由‘*’号围成的下列图形的面积。面积的计算方法是统计*号所围成的闭合曲线中水平线和垂直线交点的数目。如图所示,在10*10 的二维数组中,有*围住了15 个点,因此面积为15。
输入
一个10*10 的二维数组, 里面的数为0 和1,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
样例输出
15
一道bfs水题,不过还是要有一点小技巧
首先,找的是不被围住的点,然后统计一下除了这些点和值为1的点,用总数减去即可。
bfs找圈外的点需要注意的是不能只从左上角开始找,有也不能只从四个角开始找,因为这四个点都可能是1,所以最完善的做法是从最外面的一周的点开始bfs,因为若这些点都是1的话,那么被围住的点就是整个图形了。
这个算法别看要多次bfs,但因为被标记的点就不会再走,所以复杂度和一个点bfs是一样的。
另一种做法就是在整个图形外面再围一圈0,然后从左上角bfs 。
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 #include<cstdlib> 7 #include<queue> 8 using namespace std; 9 typedef long long ll; 10 const int maxn = 15; 11 int a[maxn][maxn], ans = 0; 12 int dx[5] = {0, 1, 0, -1, 0}, dy[5] = {0, 0, -1, 0, 1}; 13 void bfs(int x, int y) 14 { 15 queue<int>X, Y; 16 a[x][y] = 2; //标记为不是0和1的点 17 X.push(x); Y.push(y); 18 while(!X.empty()) 19 { 20 for(int i = 1; i <= 4; ++i) 21 { 22 int newx = X.front() + dx[i], newy = Y.front() + dy[i]; 23 if(newx > 0 && newx <= 10 && newy > 0 && newy <= 10 && !a[newx][newy]) 24 { 25 a[newx][newy] = 2; 26 X.push(newx); Y.push(newy); 27 } 28 } 29 X.pop(); Y.pop(); 30 } 31 32 } 33 int main() 34 { 35 freopen("area.in", " r", stdin); 36 freopen("area.out", "w", stdout); 37 for(int i = 1; i <= 10; ++i) 38 for(int j = 1; j <= 10; ++j) scanf("%d", &a[i][j]); 39 for(int i = 1; i <= 10; ++i) //从最外一圈bfs 40 { 41 if(!a[i][1]) bfs(i, 1); 42 if(!a[i][10]) bfs(i, 10); 43 if(!a[1][i]) bfs(1, i); 44 if(!a[10][i]) bfs(10, i); 45 } 46 for(int i = 1; i <= 10; ++i) 47 for(int j = 1; j <= 10; ++j) 48 if(!a[i][j]) ans++; 49 printf("%d ", ans); 50 return 0; 51 }