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更好理解,哈哈

posted @ 2024-09-14 17:14  小明算法嘎嘎猛  阅读(9)  评论(0编辑  收藏  举报