Flood fill

Flood fill 是一种BFS,由一个点向周围四个点或者八个点搜索

https://www.acwing.com/problem/content/1099/

acwing 1097 池塘计数
农夫约翰有一片 N∗M 的矩形土地。

最近,由于降雨的原因,部分土地被水淹没了。

现在用一个字符矩阵来表示他的土地。

每个单元格内,如果包含雨水,则用”W”表示,如果不含雨水,则用”.”表示。

现在,约翰想知道他的土地中形成了多少片池塘。

每组相连的积水单元格集合可以看作是一片池塘。

每个单元格视为与其上、下、左、右、左上、右上、左下、右下八个邻近单元格相连。

请你输出共有多少片池塘,即矩阵中共有多少片相连的”W”块。

输入格式
第一行包含两个整数 N 和 M。

接下来 N 行,每行包含 M 个字符,字符为”W”或”.”,用以表示矩形土地的积水状况,字符之间没有空格。

输出格式
输出一个整数,表示池塘数目。

数据范围
1≤N,M≤1000
代码

#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
const int N = 1010, M = N * N;
typedef pair<int, int> PII;
char a[N][N];
PII q[M];
bool st[N][N];
int n, m;
void bfs (int sx, int sy) {
	int hh = 0, tt = 0;
	q[0] = make_pair(sx, sy);
	st[sx][sy] = 1;
	while (hh <= tt) {
		PII t = q[hh++];
		for (int i = t.x - 1; i <= t.x + 1; i++) {
			for(int j = t.y - 1; j <= t.y + 1; j++) {
				if (i <= 0 || i > n || j <= 0 || j > m) continue;
				if (i == t.x && j == t.y) continue;
				if (a[i][j] == '.' || st[i][j]) continue;
				q[++tt] = make_pair(i, j);
				st[i][j] = 1;
			}
		}
	}
}
int main () {
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			cin >> a[i][j];
		}
	}
	int cnt = 0;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			if (a[i][j] == 'W' && !st[i][j]) {
				bfs(i, j);
				cnt ++;
			}
		}
	}
	cout << cnt << endl;
	return 0;
}

https://www.acwing.com/problem/content/1100/

acwing 1098.城堡问题
图1是一个城堡的地形图。

请你编写一个程序,计算城堡一共有多少房间,最大的房间有多大。

城堡被分割成 m∗n个方格区域,每个方格区域可以有0~4面墙。

注意:墙体厚度忽略不计。

输入格式
第一行包含两个整数 m 和 n,分别表示城堡南北方向的长度和东西方向的长度。

接下来 m 行,每行包含 n 个整数,每个整数都表示平面图对应位置的方块的墙的特征。

每个方块中墙的特征由数字 P 来描述,我们用1表示西墙,2表示北墙,4表示东墙,8表示南墙,P 为该方块包含墙的数字之和。

例如,如果一个方块的 P 为3,则 3 = 1 + 2,该方块包含西墙和北墙。

城堡的内墙被计算两次,方块(1,1)的南墙同时也是方块(2,1)的北墙。

输入的数据保证城堡至少有两个房间。

输出格式
共两行,第一行输出房间总数,第二行输出最大房间的面积(方块数)。

数据范围
1≤m,n≤50,
0≤P≤15
代码

#include <bits/stdc++.h>
#define x first
#define y second
#define N 100
using namespace std;
typedef pair<int, int> PII;
int dx[4] = {0, -1, 0, 1}, dy[4] = {-1, 0, 1, 0};
int a[N][N];
bool st[N][N];
PII q[N * N];
int n, m, cnt = 0, ans = 0;
int bfs (int sx, int sy) {
	int res = 0;
	int hh = 0, tt = 0;
	q[0] = make_pair(sx, sy);
	st[sx][sy] = 1;
	while (hh <= tt) {
		res ++;
		PII t = q[hh++];
		for (int i = 0; i < 4; i++) {
				int sx2 = t.x + dx[i], sy2 = t.y + dy[i];
				if (sx2 <= 0 || sx2 > m || sy2 <= 0 || sy2 > n) continue;
				if (a[t.x][t.y] >> i & 1) continue; 
				if (st[sx2][sy2]) continue;
				st[sx2][sy2] = 1;
				q[++tt] = make_pair(sx2, sy2);
			}	
		}
	return res;
}
int main () {
	cin >> m >> n;
	for (int i = 1; i <= m; i++) {
		for (int j = 1; j <= n; j++) {
			cin >> a[i][j];
		}
	}
	for (int i = 1; i <= m; i++) {
		for (int j = 1; j <= n; j++) {
			if (!st[i][j]) ans = max(ans, bfs(i, j)), cnt ++;
		}
	}
	cout << cnt << endl;
	cout << ans << endl;
	return 0;
}

https://www.acwing.com/problem/content/discussion/content/2781/

acwing 1106.山峰和山谷
FGD小朋友特别喜欢爬山,在爬山的时候他就在研究山峰和山谷。

为了能够对旅程有一个安排,他想知道山峰和山谷的数量。

给定一个地图,为FGD想要旅行的区域,地图被分为 n×n 的网格,每个格子 (i,j) 的高度 w(i,j) 是给定的。

若两个格子有公共顶点,那么它们就是相邻的格子,如与 (i,j) 相邻的格子有(i−1,j−1),(i−1,j),(i−1,j+1),(i,j−1),(i,j+1),(i+1,j−1),(i+1,j),(i+1,j+1)。

我们定义一个格子的集合 S 为山峰(山谷)当且仅当:

S 的所有格子都有相同的高度。
S 的所有格子都连通。
对于 s 属于 S,与 s 相邻的 s′ 不属于 S,都有 ws>ws′(山峰),或者 ws<ws′(山谷)。
如果周围不存在相邻区域,则同时将其视为山峰和山谷。
你的任务是,对于给定的地图,求出山峰和山谷的数量,如果所有格子都有相同的高度,那么整个地图即是山峰,又是山谷。

输入格式
第一行包含一个正整数 n,表示地图的大小。

接下来一个 n×n 的矩阵,表示地图上每个格子的高度 w。

输出格式
共一行,包含两个整数,表示山峰和山谷的数量。

数据范围
1≤n≤1000,
0≤w≤109

哇真的要吐,本来这道水题和前面两道差不多一样水,但是因为你理不开空调,猪脑过载debug了俩小时都没看出来队列开小了,无语,还要封校。

#include <bits/stdc++.h>
using namespace std;
#define x first 
#define y second
#define N 1010
typedef pair<int,int> PII;
int cnt1 = 0, cnt2 = 0, n;
int a[N][N];
PII q[N * N];
bool st[N][N];
void bfs (int sx, int sy) {
	int hh = 0, tt = 0, a1 = 0, b = 0;
	q[0] = make_pair(sx, sy);
	while (hh <= tt) {
		PII t = q[hh++];
		for (int i = t.x - 1; i <= t.x + 1; i++) {
			for (int j = t.y - 1; j <= t.y + 1; j++) {
				if (i == t.x && j == t.y) continue;
				if (i <= 0 || i > n || j <= 0 || j > n) continue;
				if (a[t.x][t.y] < a[i][j]) a1++; 
				else if (a[t.x][t.y] > a[i][j]) b++; 
				else {
				if (st[i][j]) continue;
				q[++tt] = make_pair(i, j);	
				st[i][j] = 1;
				}
			}
		}
	}
	if (!b) cnt2 ++;
	if (!a1) cnt1 ++;
}
int main () {
	cin >> n;

	for (int i = 1; i <= n; i++) 
		for (int j = 1; j <= n; j++) cin >> a[i][j];
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			if (!st[i][j]){
				bfs(i, j);
			}
		}
	}
	cout << cnt1 << " " << cnt2 << endl;
	return 0;
}

posted @ 2022-04-24 16:08  misasteria  阅读(36)  评论(0编辑  收藏  举报