你有一张某海域 N×N像素的照片,”.”表示海洋、”#”表示陆地,如下所示:
.......
.##....
.##....
....##.
..####.
...###.
.......
其中”上下左右”四个方向上连在一起的一片陆地组成一座岛屿,例如上图就有 22 座岛屿。
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。
具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。
例如上图中的海域未来会变成如下样子:
.......
.......
.......
.......
....#..
.......
.......
请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。
输入格式
第一行包含一个整数N。
以下 N 行 N 列,包含一个由字符”#”和”.”构成的 N×N 字符矩阵,代表一张海域照片,”#”表示陆地,”.”表示海洋。
照片保证第 11 行、第 11 列、第 N行、第 N 列的像素都是海洋。
输出格式
一个整数表示答案。
数据范围
1≤N≤1000
输入样例1:
7
.......
.##....
.##....
....##.
..####.
...###.
.......
输出样例1:
1
输入样例2:
9
.........
.##.##...
.#####...
.##.##...
.........
.##.#....
.#.###...
.#..#....
.........
输出样例2:
1
题意:
求出在给定的海域中有多少个岛屿会被淹没。
分析:
我们应该遍历所有岛屿,判断每个岛屿是否会被淹没。遍历岛屿就是连通块问题,那么如何判断这个岛屿是否会被淹没呢?我们可以统计这个岛屿的陆地个数和会被淹没的陆地的个数,如果两个相等,那么该岛屿会被淹没,答案++。
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
typedef pair<int,int> PII;
const int N=1010;
int n,cnt,flag,bound,ans;
int st[N][N];//判断该点是否走过
char g[N][N];
int dir[4][2]={0,1,0,-1,1,0,-1,0};
void bfs(int x,int y){
queue<PII>q;
q.push({x,y});
st[x][y]=1;
while(!q.empty()){
//cout<<"1"<<endl;
PII t=q.front();
q.pop();
++ans;
for(int i=0;i<4;++i){
int xx=t.first+dir[i][0],yy=t.second+dir[i][1];
if(xx>=0&&xx<n&&yy>=0&&yy<n&&g[xx][yy]=='.'){
++bound;
break;
}
}
for(int i=0;i<4;++i){
int xx=t.first+dir[i][0],yy=t.second+dir[i][1];
if(xx>=0&&xx<n&&yy>=0&&yy<n&&g[xx][yy]=='#'&&!st[xx][yy]){
st[xx][yy]=1;
q.push({xx,yy});
}
}
}
}
int main()
{
cin>>n;
for(int i=0;i<n;++i){
cin>>g[i];
getchar();
}
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
if(!st[i][j]&&g[i][j]=='#'){
bound=ans=0;
bfs(i,j);
if(ans==bound){
++cnt;
}
}
}
}
cout<<cnt;
return 0;
}