#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
typedef pair<int, int>PII;//要定义在std的后面
const int N = 60;
int mp[N][N];//创建图
bool sea[N][N];//记录遍历过的海
bool road[N][N];//记录遍历过的岛
int m, n;
int ans;
//海的移动向量
int seax[8] = { -1, -1, -1, 0, 1, 1, 1, 0 };//对应j
int seay[8] = { -1, 0, 1, 1, 1, 0, -1, -1 };//对应i
//岛的移动向量
int roadx[4] = { -1, 0, 1, 0 };
int roady[4] = { 0, 1, 0, -1 };
//检查函数
int check(int x, int y)
{
return x >= 0 && x <=m-1 && y >= 0 && y <= n-1 && sea[x][y] == 0 && mp[x][y] == 0;
//没有出界,并且这个海没有访问过
}
int check2(int x, int y)
{
return x >=0 && x <=m-1 && y >=0 && y <=n-1 && road[x][y] == 0 && mp[x][y] == 1;
//没有出界,这块陆地没有访问过
}
void dfs(int x, int y)//dfs寻找岛屿,给这个岛所有相连的岛打上标记
{
//停止条件遍历完所有的点,没有1可以遍历
queue<PII>q2;
road[x][y] = true;//这是个岛我们将它标记为1,表示我们已经走过
q2.push({ x,y });
while (!q2.empty())
{
PII s = q2.front();
q2.pop();
for (int i = 0; i < 4; i++)
{
int dx = s.first + roadx[i];//在为海打上标记的过程中,
int dy= s.second + roady[i];//往四个方向找和他相邻的陆地
if (check2(dx, dy))
{
road[dx][dy] = true;//找到陆地,打上标记
q2.push({ dx,dy });//将找到的数压入栈
//if(dfs(dx, dy))return 1;
}
}
}
}
void bfs(int x,int y)//i,j
{
queue<PII>q;
sea[x][y] = 1;
q.push({ x, y });
while (!q.empty())
{
PII top = q.front();
q.pop();
for (int i = 0; i < 8; i++)
{
int nex = top.first+seax[i];//往八个方向找和他相邻的海
int ney = top.second+seay[i];
if (check(nex,ney))
{
sea[nex][ney] = true;//将遍历的海打上标记
q.push({ nex,ney });
}
if (check2(nex, ney))
{
ans++;
dfs(nex, ney);
}
}
}
}
void solve()
{
cin >> m >> n;
memset(mp, 0, sizeof(mp));
memset(road, 0, sizeof(road));//因为有多组数据,每次循环前进行清空
memset(sea, 0, sizeof(sea));
ans = 0;
for (int i = 0; i < m; i++)
{
string s;
cin >> s;
for (int j = 0; j < n; j++)
{
mp[i][j] = s[j] - '0';
}
}
bool s1 = 0;
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
if (!i || i == m - 1 || !j || j == n - 1)//i=0m说明在第一行,i=n-1,说明在最后一行
{
if (!mp[i][j] && !sea[i][j])
{
s1 = 1;
bfs(i,j);//和直角坐标系里点的x,y是反过来的
}
}
}
}
if (!s1)ans = 1;
cout << ans << endl;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
/*遍历所有的海,并且遍历与他相邻的陆地,将陆地相邻的部分打上标记,遍历多少次陆地就说明找到了多少个岛,*/
https://www.dotcpp.com/oj/submit_status.php?sid=15454190
测试链接