bfs与dfs ,全球变暖——蓝桥problems178
问题描述:
.......
.##....
.##....
....##.
..####.
...###.
.......
有一张还以N*N的像素照片,“.”表示海洋,“#”表示陆地,其中上下左右能连在一起的陆地称作岛屿,例如上图有两座岛屿,由于全球气候变暖,靠经海洋的陆地会被淹没,问图中有多少座岛屿会被完全淹没
.......
.......
.......
.......
....#..
.......
.......
输入:
第一行输入一个整数N,之后的N*N输入该像素照片,保证第一行第一列最后一行最后一列都为海洋。
输出:
输出一个整数表示答案
问题分析:
要找到所有的岛屿,如果该岛屿存在高地则该岛屿不会被淹没,即存在一片陆地其周围都是陆地的岛屿,可以使用DFS,BFS进行搜索,由于每个像素点都需要搜索,一共有N*N个点那么时间复杂度为O(N**2),好像不可能再优了
DFS代码:
#include<iostream>
using namespace std;
const int N = 1010;
char mp[N][N];
int vis[N][N] = { 0 };
int d[4][2] = { {0,1},{0,-1},{1,0},{-1,0} };
int flag;
void dfs(int x, int y) {
vis[x][y] = 1; //标记为该节点已经查过,与下面的dfs(nx, ny);搭配
//条件
if (mp[x][y - 1] == '#' && mp[x][y + 1] == '#' && mp[x - 1][y] == '#' && mp[x + 1][y] == '#') {
flag = 1; //flag=1代表有高地,该岛屿不会被淹没
}
//搜索四个周围方向
for (int i = 0; i < 4; i++) {
int nx = x + d[i][1]; int ny = y + d[i][2];
if (vis[nx][ny] == '0' && mp[nx][ny] == '# ') { //注意这个判断语句两个条件的先后,这里其实是在岛屿内搜索了,需要把所有的陆地都标记
dfs(nx, ny);
}
}
}
int main() {
int n; cin >> n;
for (int i = 0; i < n; i++) {
cin >> mp[i];
}
int ans = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (mp[i][j] == '#' && vis[i][j] == 0) { //这个是整图搜索,所以是这样的条件先后
flag = 0;
dfs(i, j);
if (flag == 0) {
ans++;
}
}
}
}
cout << ans << endl;
return 0;
}
bfs代码:
#include<iostream>
#include <queue>
using namespace std;
const int N = 1010;
char mp[N][N];
int vis[N][N];
int dir[4][2] = { {0,1},{0,-1},{1,0},{-1,0} };
int flag;
void bfs(int x, int y) {
queue < pair<int, int>>q;
q.push({ x, y });
vis[x][y] = 1;
//dfs可以利用递归实现查询,而bfs需要利用循环
while (q.size()) {
pair<int, int>t = q.front();
q.pop(); //需要将队首删除
int tx = t.first; int ty = t.second;
if (mp[tx][ty - 1] == '#' && mp[tx][ty - 1] == '#' && mp[tx - 1][ty] == '#' && mp[tx + 1][ty] == '#') {
flag = 1;
}
for (int i = 0; i < 4; i++) {
//上下左右四个方向依次进队
int nx = tx + dir[i][1]; int ny = ty + dir[i][2];
if (vis[nx][ny] == 0 && mp[nx][ny] == '#') {
vis[nx][ny] == 1; //这里和dfs不同,记得标记
q.push({ nx,ny });
}
}
}
}
int main() {
int n; cin >> n;
for (int i = 0; i < n; i++) {
cin >> mp[n];
}
int ans = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (mp[i][j] == '#' && vis[i][j] == 0) {
flag = 0;
bfs(i, j);
if (flag == 0) {
ans++;
}
}
}
}
cout << ans << endl;
return 0;
}
由此可见,dfs实际上就是递归,而bfs就是循环,相比之下好像bfs更好理解,哈哈