输入输出样例
示例
输入
7
.......
.##....
.##....
....##.
..####.
...###.
.......
输出
1
运行限制
- 最大运行时间:1s
- 最大运行内存: 256M
官网的题目上标出了dfs,好吧,那直接往dfs去想就好了。什么样的岛不会被淹没呢,很明显,是他四周都不是海,那就不会被淹没。
那么我们如何来dfs呢?我们把dfs里边分为两部分,一部分用来判定这个岛会不会被淹没,另外一个部分用来dfs递归四周的点。
对第一个部分,其实就是一个点往四个方向找找看是否都不是'.',如果都不是,那么说明这个岛存在一个这样不会被淹没的点,那么后续遍历岛就都不需要再计算第一个部分了。为什么判断条件是都不是‘.’而不是都是‘#’呢,原因是这样的,在我们进行第一部分之后,我们将这个点的字符置为一个'*',这样有什么好处呢?好处在于,我们之后在main中不会再次重复访问同一个岛上的点,而且对原来岛屿的计数也是准确的了。
第二个部分其实就是遍历周围的点继续dfs
代码如下所示
#include <iostream>
using namespace std;
#define N 1001
char m[N][N];
int n;
int d[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
bool flag;
int before,after;
void dfs(int x,int y)
{
if(flag==false)
{
int cnt=0;
for(int i=0;i<4;++i)
{
int dx=x+d[i][0];
int dy=y+d[i][1];
if(m[dx][dy]!='.')
{
cnt++;
}
}
if(cnt==4)
{
after++;
flag=true;
}
}
m[x][y]='*';
for(int i=0;i<4;++i)
{
int dx=x+d[i][0];
int dy=y+d[i][1];
if(m[dx][dy]=='#')
{
dfs(dx,dy);
}
}
}
int main()
{
// 请在此输入您的代码
cin>>n;
for(int i=1;i<=n;++i)
{
for(int j=1;j<=n;++j)
{
cin>>m[i][j];
}
}
for(int i=2;i<n;++i)
{
for(int j=2;j<n;++j)
{
if(m[i][j]=='#')
{
before++;
flag=false;
dfs(i,j);
}
}
}
cout<<before-after;
return 0;
}