题目描述
你有一张某海域 NxNNxN 像素的照片,".“表示海洋、”#"表示陆地,如下所示:
.......
.##....
.##....
....##.
..####.
...###.
.......
其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有 2 座岛屿。
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。
例如上图中的海域未来会变成如下样子:
.......
.......
.......
.......
....#..
.......
.......
请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。
输入描述
第一行包含一个整数 N (1≤N≤1000)。
以下 N 行 N 列代表一张海域照片。
照片保证第 1 行、第 1 列、第 N 行、第 N 列的像素都是海洋。、
输出一个整数表示答案。
输入输出样例
示例
输入
7
.......
.##....
.##....
....##.
..####.
...###.
.......
输出
1
思路:
根据题意,只要是连接在一起的陆地就可以构成岛屿,实例就只有两块岛屿,只用看这两块岛屿中是不是有没有沉没的陆地就好了
沉没的定义是上下左右有海洋像素就可以了,所以先全部搜索了一遍,每一个陆地是否会沉没,再去用dfs搜索每一块岛屿,每一次dfs都把这次搜到的相连的陆地标为true,就保证了每次main里的dfs次数就是岛屿次数。
每次main都用一个ok来查这块岛屿是否有没沉没的陆地,有就把ok标成true,但还是要继续标剩下相连的陆地,因为它们是一块岛屿
#include <bits/stdc++.h>
using namespace std;
char mp[1005][1005];
bool vis[1005][1005];
bool is_on[1005][1005]; //是否在海上
int dir[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
int n,ans;
bool ok;
//是否沉到海里
bool find(int x,int y){
for (int i = 0; i < 4; i++) {
int tx = x+dir[i][0];
int ty = y+dir[i][1];
if (mp[tx][ty]=='.') return true;
}
return false;
}
void dfs(int x,int y){
if (vis[x][y] == true) return;
vis[x][y] = true;
if (is_on[x][y]) ok = true;
for (int i = 0; i < 4; i++) {
int tx = x+dir[i][0];
int ty = y+dir[i][1];
if (mp[tx][ty]=='#')dfs(tx,ty);
}
}
int main(){
cin >> n;
for (int i = 0; i < n; i++) {
cin >> mp[i];
}
for (int i = 1; i < n-1; i++) {
for (int j = 1; j < n-1; j++) {
if (mp[i][j]=='#'){
if (!find(i,j)) is_on[i][j] = true;
}
}
}
for (int i = 1; i < n-1; i++) {
for (int j = 1; j < n-1; j++) {
if (mp[i][j] == '#'&&vis[i][j]==false){
ok = false;
dfs(i,j);
if (!ok) ans++;
}
}
}
cout << ans;
return 0;
}