https://www.acwing.com/problem/content/4962/
陆地搜上下左右4个方向
海洋搜8个方向,如果搜到陆地就bfs_land搜索整块陆地,每一次使用bfs_land证明答案+1
开大数组,将图的外圈覆盖一圈海,从海开始搜起,如果是内海(被陆地环住的海)就不会被搜到,同理内海中的岛也不会被搜到
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = 110;
int t, n, m, ans;
int dx_land[4] = {0, -1, 1, 0}, dy_land[4] = {-1, 0, 0, 1};
int dx_sea[8] = {-1, 0, 1, -1, 1, -1, 0, 1}, dy_sea[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
char s[N][N];
bool st[N][N];
void bfs_land(int a, int b){
ans ++;
queue<PII> q;
q.push({a, b});
st[a][b] = true;
while(q.size()){
PII t = q.front();
q.pop();
for(int i = 0; i < 4; i++){
int x = t.first + dx_land[i], y = t.second + dy_land[i];
if(x >= 0 && x <= n + 1 && y >= 0 && y <= m + 1 && !st[x][y] && s[x][y] == '1'){
q.push({x, y});
st[x][y] = true;
}
}
}
}
void bfs_sea(int a, int b){
queue<PII> q;
q.push({a, b});
st[a][b] = true;
while(q.size()){
PII t = q.front();
q.pop();
for(int i = 0; i < 8; i++){
int x = t.first + dx_sea[i], y = t.second + dy_sea[i];
if(x >= 0 && x <= n + 1 && y >= 0 && y <= m + 1 && !st[x][y]){
if(s[x][y] == '1') bfs_land(x, y);
else{
q.push({x, y});
st[x][y] = true;
}
}
}
}
}
void solve(){
cin >> n >> m;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
cin >> s[i][j];
bfs_sea(0, 0);
}
int main(){
cin >> t;
while(t --){
ans = 0;
memset(st, 0, sizeof st);
memset(s, '0', sizeof s);
solve();
cout << ans << endl;
}
return 0;
}