蓝桥杯——全球变暖(dfs)

题目描述
你有一张某海域 N×N 像素的照片,”.”表示海洋、”#”表示陆地,如下所示:

.......
.##....
.##....
....##.
..####.
...###.
.......


其中”上下左右”四个方向上连在一起的一片陆地组成一座岛屿,例如上图就有 2 座岛屿。

由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。

具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。

例如上图中的海域未来会变成如下样子:

.......
.......
.......
.......
....#..
.......
.......


请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。

输入格式
第一行包含一个整数N 

以下 N 行 N 列,包含一个由字符”#”和”.”构成的 N × N 字符矩阵,代表一张海域照片,”#”表示陆地,”.”表示海洋

照片保证第 1 行、第 1 列、第 N 行、第 N 列的像素都是海洋。

输出格式
一个整数表示答案。

数据范围
1 ≤ N ≤ 1000

【样例输入】

7 
.......
.##....
.##....
....##.
..####.
...###.
.......  

【样例输出】
 

1

思路

遍历整个图片,遇到陆地‘#’则进入dfs搜索,并将已访问过的坐标标记为‘&’;

在dfs中要做这么几件事情:1.判断传入的坐标是否越界,越界则返回;2.判断该坐标位置是否是陆地且未被访问过,不是陆地或已被访问过则返回;3.若到达的是一块未被访问过的陆地,则将其标记为代表访问过的符号‘&’,并判断该坐标是否会沉没,然后分上下左右四个方向继续进行搜索。

题解

#include <iostream>
#include <vector>
using namespace std;

int sinking; //用于判断该岛屿是否会沉没
void dfs(vector<vector<char>>& grid, int i, int j);
bool inArea(vector<vector<char>>& grid, int i, int j);
int main()
{
	int k;
	cin >> k;
	vector<vector<char>> grid(k,vector<char>(k));
	for (int i = 0; i < k; i++) {
		for (int j = 0; j < k; j++) {
			char c;
			cin >> c;
			if (c == '\n') {
				j--;
				continue;
			}
			grid[i][j] = c;
		}
	}
	int ans = 0;
	int cnt = 0;
	for (int i = 0; i < k; i++) {
		for (int j = 0; j < k; j++) {
			sinking = 1;
			if (grid[i][j] == '#') {
				cnt++;
				dfs(grid, i, j);
				if (sinking == 1) {
					ans++;
				}
				
			}
		}
	}
	//cout << "起始岛屿数量:" << cnt << endl;
	cout << ans;
}
void dfs(vector<vector<char>>& grid, int i, int j)
{
	if (!inArea(grid, i, j)) {
		return;
	}
	if (grid[i][j] != '#') {
		return;
	}
	grid[i][j] = '&';
	bool flag = true;
    //如果四个方向中相邻的有海域,则这个坐标的陆地会沉没
	if (inArea(grid, i - 1, j) && grid[i - 1][j] == '.') flag = false;
	if (inArea(grid, i + 1, j) && grid[i + 1][j] == '.') flag = false;
	if (inArea(grid, i, j - 1) && grid[i][j - 1] == '.') flag = false;
	if (inArea(grid, i, j + 1) && grid[i][j + 1] == '.') flag = false;
    //如果上下左右都是陆地,则该坐标不会沉没,进而该坐标所在的岛屿会有保留的部分
	if (flag) {
		sinking = 0;
	}
	dfs(grid, i - 1, j);
	dfs(grid, i + 1, j);
	dfs(grid, i, j - 1);
	dfs(grid, i, j + 1);
}
bool inArea(vector<vector<char>>& grid, int i, int j)
{
	return i >= 0 && i < grid.size() && j >= 0 && j < grid[0].size();
}

  • 13
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值