Flood fill
Flood fill 是一种BFS,由一个点向周围四个点或者八个点搜索
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;
}
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;
}
本文作者:misasteria
本文链接:https://www.cnblogs.com/misasteria/p/16186307.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步