一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情。
思路
很明显,这个题目就是一个深度优先搜索的题目。第一,我们先明白岛屿这个概念,上下左右四个方向连在一起的陆地就是一座岛屿,实际上只要是两块陆地且两块以上陆地相邻,那么它就是一个岛屿,就算是一个单独的陆地,它也是一个岛屿。很多人没有明白这个导致做不出题目。第二个要点是从陆地开始深搜,如果这是一块陆地,那么我们就可以开始搜索了,并且我们直接默认是从新的一个岛屿开始搜索。如果这不是一块陆地并且它已经被搜索过了,那么我们也不必要从这一块陆地开始搜索了。当我们开始搜索时,我们判断这块陆地的上下左右是否都是陆地,如果都是陆地,那么这一块岛屿就不可能会全被淹没。如果存在这样的一块陆地,那么这块岛屿就不会淹没,如果不存在,这块岛屿就会淹没,我们就可以计数加一。全部遍历完整个海域,这道题目就完成了。
代码
#include <iostream>
using namespace std;
char Map[1005][1005];
int N;
int Mx[4] = {1, 0, -1, 0}, My[4] = { 0, 1, 0, -1};
bool flag = false;
bool Check1(int x, int y){
for(int i = 0; i < 4; i++)
if(Map[x + Mx[i]][y + My[i]] == '.')
return true;
return false;
}
bool Check2(int x, int y){
if(x >= 0 && y >= 0 && x < N && y < N && Map[x][y] == '#')
return true;
return false;
}
void DFS(int x, int y){
Map[x][y] = '*';//判断是否走过
if(!Check1(x, y)) flag = true;
for(int i = 0; i < 4; i++)
if(Check2(x + Mx[i], y + My[i]))
DFS(x +Mx[i], y + My[i]);
}
int sov(){
int ans = 0;
for(int i = 0; i < N; i++)
for(int j = 0; j < N; j++)
if(Map[i][j] == '#'){
flag = false;
DFS(i, j);
if(!flag) ans++;
}
return ans;
}
int main()
{
cin >> N;
for(int i = 0; i < N; i++)
for(int j = 0 ; j < N; j++)
cin>>Map[i][j];
cout<<sov();
return 0;
}