题目描述
编程计算由"1"围成的下列图形的面积。面积计算方法是统计"1"所围成的闭合曲线中"0"点的数目。如图所示,在10*10的二维数组中,"1"围住了15个点,因此面积为15。
输入
测试次数t每组测试数据格式为:
数组大小m,n
一个由0和1组成的m*n的二维数组
输出 对每个二维数组,输出符号"1"围住的"0"的个数,即围成的面积。假设一定有1组成的闭合曲线,但不唯一。
样例输入 2
10 10
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
5 8
0 1 1 0 0 1 1 0
1 0 1 0 1 0 0 1
0 1 0 1 0 0 1 0
0 1 0 0 1 1 1 0
0 0 0 0 0 0 0 0
样例输出
15
5
我们可能没办法很好判断哪些0被1包围,但是我们可以很简单的把没有被1包围的0判断出来,
我们把输入的地图放大一圈,只要从起点map[0][0]能到达的地方,都是没有被1包围的,
完美的符合了第二个示例
下图为放大一圈的地图,并且map[0][0] = 1设为起点;
当所有没有被1包围的0也改为1后,我们就可以数出多少的0被包围
#include<iostream>
using namespace std;
class Map {
private:
int **map;
int m,n;
public:
Map(int _m, int _n) {
m = _m;
n = _n;
map = new int*[m+2];
for(int i = 0; i < m+2; i++) {
map[i] = new int[n+2];
}
for(int i = 0; i < m+2; i++) {
for(int j = 0; j < n+2; j++) {
map[i][j] = 0;
}
}
map[0][0] = 1; //设起点为 1
for(int i = 1; i < m+1; i++) {
for(int j = 1; j < n+1; j++) {
cin>>map[i][j];
}
}
}
~Map(){
for(int i = 0; i < m + 2; i++){
delete []map[i];
}
delete []map;
}
int walk_map(int x,int y) {
if(y+1 != n+2 && map[x][y+1] == 0) { //向右走 ,y+1 != n+2是防止越界
map[x][y+1] = 1;
walk_map(x,y+1);
}
if(x+1 != m+2 && map[x+1][y] == 0) { //向下走
map[x+1][y] = 1;
walk_map(x+1,y);
}
if(y-1 != -1 && map[x][y-1] == 0) { //向左走
map[x][y-1] = 1;
walk_map(x,y-1);
}
if(x-1 != -1 && map[x-1][y] == 0) { //向上走
map[x - 1][y] = 1;
walk_map(x - 1,y);
}
}
int count(){
int num = 0;
for(int i = 1; i < m + 1; i++){
for(int j = 1; j < n + 1; j++){
if(map[i][j] == 0)
num++;
}
}
return num;
}
};
int main() {
int m,n;
int t;
cin>> t;
while(t--) {
cin>>m>>n;
Map _map(m,n);
_map.walk_map(0,0);
cout<<_map.count()<<endl;
}
return 0;
}