之前我们介绍了 bfs算法
在二维,三维地图中的应用,现在我们接续进行拓展,解锁floodfill
算法,准确的来说是用 bfs算法
解决联通块问题。后续还会更新 bfs算法
有关内容,喜欢的小伙伴可以点个关注啦。
你有一张某海域 N×N 像素的照片,”.”表示海洋、”#”表示陆地,如下所示:
.......
.##....
.##....
....##.
..####.
...###.
.......
其中”上下左右”四个方向上连在一起的一片陆地组成一座岛屿,例如上图就有 2 座岛屿。
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围被海水淹没。
具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。
例如上图中的海域未来会变成如下样子:
.......
.......
.......
.......
....#..
.......
.......
请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。
输入格式
第一行包含一个整数N。
以下 N 行 N 列,包含一个由字符”#”和”.”构成的 N×N 字符矩阵,代表一张海域照片,”#”表示陆地,”.”表示海洋。
照片保证第 1 行、第 1 列、第 N 行、第 N 列的像素都是海洋。
输出格式
一个整数表示答案。
数据范围
1≤N≤1000
输入样例1:
7
.......
.##....
.##....
....##.
..####.
...###.
.......
输出样例1:
1
输入样例2:
9
.........
.##.##...
.#####...
.##.##...
.........
.##.#....
.#.###...
.#..#....
.........
输出样例2:
1
照片保证第 1 行、第 1 列、第 N 行、第 N 列的像素都是海洋。
这里想要不考虑边界问题,输入的初始下标要设为 1 开始,这样就可以保证数组不越界,并且由题目的意思可得,外围的圈都是海洋,只要下标从1 开始,我们就可以不用考虑bfs算法当中的边界问题。
如何判定这是一个不会被淹没的岛屿呢?
首先我们要明白联通块的概念------连在一起的快;
接着我们定义一个沿岸元素
具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。
也就是说只要一个‘#’
旁边有海洋,我们就可以认定该陆地元素‘#’
是沿岸元素块。
只要我们的联通块的所有总数=沿岸元素的所有总数,那么我们就可以判定这是个会被淹没的岛屿
答案就是利用我们的 bfs算法
将目标元素进行宽度优先搜索,将搜索到的的‘#’
,标记,继续搜索那些没有被标记的‘#’
。
详细的解释都在代码的注释里头啦
#include
#include
#include
using namespace std;
const int N =1e3 + 7;
char g[N][N];//用来存放地图
bool st[N][N];//用来统计那些点已经被搜索过了
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
typedef pair<int,int> PII;
void bfs(int i,int j,int &total,int &bound){
//这里使用的引用符号是&,要将值传回去。
st[i][j]=true;
queue<PII> q;
q.push({i,j});
while(!q.empty()){
auto t=q.front();
q.pop();
total++;
bool flag=false;//这个flag用于沿岸元素的判断
for(int i=0;i<4;i++){
int x=t.first+dx[i];
int y=t.second+dy[i];
if(g[x][y]=='#' && !st[x][y]){
q.push({x,y});
st[x][y]=true;
}
if(g[x][y]=='.'){//只要有一个旁边元素是‘.’就可以判断其为沿岸元素
flag=true;
}
}
if(flag) bound++;//如果判断成功,沿岸元素++
}
}
int main(){
int n;cin>>n;
memset(g,'.',sizeof g);//在题目分析中的说明里,
//这个代码可要可不要,假如没有题目中的话,我们就要加上这行代码了
for(int i=1;i<=n;i++) cin>>g[i];
int res=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(!st[i][j] && g[i][j]=='#'){
int total=0,bound=0;
bfs(i,j,total,bound);
if(total==bound) res++;//判断这个岛屿是否会被淹没
}
}
}
cout<<res<<endl;
return 0;
}
后期还放出大学生 web大作业【制作一个门户网站】,感兴趣的小伙伴可以点个关注啦