大致思路:题目要求子岛屿的个数:先进行dfs图的染色区分哪些是真正的海哪些是可视为陆地的海(如果是子岛屿则周围的海一定不会被染色此时可以将子岛屿及其周围的海看成是陆地)
然后再去进行dfs去寻找岛的个数
#include<iostream>
#include<string.h>
using namespace std;
bool flag[60][60];
char arr[60][60];
int x[8] = {0, 0, 1, -1, 1, 1, -1, -1};
int y[8] = {1, -1, 0, 0, -1, 1, 1, -1};
int n,m ;
int res;
void dfs_f(int ax,int ay) {
if(arr[ax][ay]=='1')
return ;
arr[ax][ay]='2';
flag[ax][ay]=1;
for(int i = 0; i<8; i++) {
int dx = ax+x[i];
int dy = ay+y[i];
//八个坐标
if(dx>=0&&dx<n&&dy>=0&&dy<m&&!flag[dx][dy]) { //坐标不出界且没有访问过 (所有)
//符合基本要求但不合适 标记访问过
if(arr[dx][dy]=='0') { //特地要求符合 上色
arr[dx][dy]='2';
dfs_f(dx,dy);//
} else {
flag[dx][dy]=1;
}
flag[dx][dy]=1;
}
}
}
void dfs_s(int ax,int ay) {
if(arr[ax][ay]=='2')//真海水--就--跳过
return ;
flag[ax][ay]=1;
for(int i = 0; i<4; i++) {
int dx = ax+x[i];
int dy = ay+y[i];
//四个坐标
if(dx>=0&&dx<n&&dy>=0&&dy<m&&!flag[dx][dy]) { //坐标不出界且没有访问过 (所有)
//符合基本要求但不合适 标记访问过
if(arr[dx][dy]=='0'||arr[dx][dy]=='1') { //是陆地就继续搜
//arr[dx][dy]=1;
flag[dx][dy]=1;
dfs_s(dx,dy);
} else {
flag[dx][dy]=1;
}
}
}
}
int main() {
int k;
cin>>k;
for(int a =0; a<k; a++) {
cin>>n>>m;
for(int i=0; i<n; i++) {
for(int j = 0; j<m; j++) {
cin>>arr[i][j];
}
}
for(int i=0; i<n; i++) {
for(int j = 0; j<m; j++) {
if((i==0||i==n-1||j==0||j==m-1)) {
dfs_f(i,j);
}
}
}
memset(flag, 0, sizeof flag);//重置标记数组
for(int i=0; i<n; i++) {
for(int j = 0; j<m; j++) {
if(!flag[i][j]&&arr[i][j]!='2') { //如果没有被访问过
res++;
dfs_s(i,j);
}
}
}
cout<<res<<endl;
res = 0;
memset(flag, 0, sizeof flag);
}
return 0;
}