洛谷 P8662 [蓝桥杯 2018 省 AB] 全球变暖(C++)(BFS)

目录

1.题目

## 题目描述

## 样例 #1

## 提示

2.AC


1.题目

[蓝桥杯 2018 省 AB] 全球变暖 - 洛谷

## 题目描述

你有一张某海域 $N \times N$ 像素的照片,`.` 表示海洋、 `#` 表示陆地,如下所示:

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

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

由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。

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

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

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

## 输入格式

第一行包含一个整数 $N$。$(1 \le N \le 1000)$。

以下 $N$ 行 $N$ 列代表一张海域照片。

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

## 输出格式

一个整数表示答案。

## 样例 #1

### 样例输入 #1


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


### 样例输出 #1

1

## 提示

时限 1 秒, 256M。蓝桥杯 2018 年第九届省赛

2.AC

#include <iostream>
#include <cstring>
#include <queue> 
using namespace std;

int n, sum, flag;
int v[1010][1010], f[1010][1010];
int dx[4]={0,0,-1,1},dy[4]={1,-1,0,0};
char a[1010][1010];

struct node{
	int x, y;
}p, t;

queue<node> q;

void bfs1(int u1, int u2) {
	p.x = u1, p.y = u2;
	v[u1][u2] = 1;
	q.push(p);
	while (!q.empty()) {
		t = q.front(), q.pop();
		for (int i = 0; i < 4; i++) {
			int cx = t.x + dx[i];
			int cy = t.y + dy[i];
			if (cx<0 || cy<0 || cx>=n || cy>=n) continue;
			if (!v[cx][cy]) {	
				if (a[cx][cy]=='.') {
					f[t.x][t.y] = 1;
				} else {
					p.x = cx, p.y = cy;
					q.push(p);
					v[cx][cy] = 1;
				}
			}
		}
	}
}

void bfs2(int u1, int u2) {
	p.x = u1, p.y = u2;
	v[u1][u2] = 1;
	q.push(p);
	while (!q.empty()) {
		t = q.front(), q.pop();
		for (int i = 0; i < 4; i++) {
			int cx = t.x + dx[i];
			int cy = t.y + dy[i];
			if (cx<0 || cy<0 || cx>=n || cy>=n) continue;
			if (!v[cx][cy]&&a[cx][cy]=='#') {
			if(!f[cx][cy]) flag = 1;
				p.x = cx, p.y = cy;
				q.push(p);
				v[cx][cy] = 1;
				}
			}
		}
}

int main () {
	memset(v,0,sizeof(v));
	memset(f,0,sizeof(f));
	cin>>n;
	for (int i = 0; i < n; i++) {
		cin>>a[i];
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			if (a[i][j]=='#'&&!v[i][j]) {
				bfs1(i,j);
				sum++;
			}
		}
	}
	memset(v,0,sizeof(v));
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			flag = 0;
			if (a[i][j]=='#'&&!v[i][j]) {
				bfs2(i,j);
				if (flag) {
					sum--;
				}
			}
		}
	}
	cout<<sum;
	return 0;
}

### 关于蓝桥杯 C++ 全球变暖题目及其解法 #### 题目描述 给定一张大小为 \( N \times N \) 的海域照片,其中 "." 表示海洋,"#" 表示陆地。由于全球变暖的影响,一些岛屿可能会被海水淹没。每次涨潮时,所有的边界上的 "#" 将会变成 "."。求经过若干次涨潮之后剩余的岛屿数量。 --- #### 解题思路 该问题可以通过广度优先搜索 (BFS) 来解决。以下是具体的分析: 1. **初始状态处理** 输入矩阵表示地图的状态,"." 和 "#" 分别代表不同的区域。需要先标记出哪些位置会被第一次涨潮影响到。这些位置通常是与边界相邻的 "#"[^1]。 2. **模拟涨潮过程** 使用 BFS 对受影响的位置进行扩展。对于每一个受到影响的格子,将其变为 ".", 并继续检查其上下左右四个方向是否有新的 "#" 可以被波及[^1]。 3. **统计最终结果** 经过多次迭代直到不再有新变化为止,最后遍历整个地图来计算还剩下多少独立的岛屿(即未被水覆盖的部分)。 --- #### 实现代码 下面提供了一个基于上述逻辑实现的 C++ 程序: ```cpp #include <iostream> #include <queue> using namespace std; const int MAX_N = 50; char grid[MAX_N][MAX_N]; bool visited[MAX_N][MAX_N]; int n; // 方向数组定义移动方式 上下左右 int dx[] = {-1, 1, 0, 0}; int dy[] = {0, 0, -1, 1}; void bfs(int x, int y){ queue<pair<int,int>> q; q.push({x,y}); visited[x][y]=true; while(!q.empty()){ pair<int,int> current=q.front(); q.pop(); for(int d=0;d<4;++d){ int nx=current.first+dx[d], ny=current.second+dy[d]; if(nx>=0 && nx<n && ny>=0 && ny<n && !visited[nx][ny] && grid[nx][ny]=='#'){ visited[nx][ny]=true; q.push({nx,ny}); grid[nx][ny]='.'; // 模拟淹沒過程 } } } } int countIslands(){ int islands=0; for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(grid[i][j]=='#'&&!visited[i][j]){ bfs(i,j); islands++; } return islands; } int main(){ cin >> n; for(int i=0;i<n;i++) { string line; cin >> line; for(int j=0;j<n;j++) grid[i][j]=line[j]; } // 初始化访问标志并找到所有边界的'#' for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ if((i==0 || i==n-1 || j==0 || j==n-1)&&grid[i][j]=='#') bfs(i,j); // 处理边缘部分 } } cout << countIslands() << endl; } ``` --- #### 结果解释 通过执行以上程序,可以得到在经历一系列涨潮事件后仍然存在的岛屿数目。这正是本题所要求的结果。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值