P1596 [USACO10OCT] Lake Counting S - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题目描述
就是有一个二维空间
里面有水的用‘W’表示,无水的用‘.’表示
每个单元格视为与其上、下、左、右、左上、右上、左下、右下八个邻近单元格相连。
问共有几个池塘。
输入样例
10 12
W........WW.
.WWW.....WWW
....WW...WW.
.........WW.
.........W..
..W......W..
.W.W.....WW.
W.W.W.....W.
.W.W......W.
..W.......W.
输出样例
3
样例解析
一共有三个池塘:
其实就是让我们找连通块的。
解题思路
按层遍历,如果是水我们就把水四周是水的地方全部遍历一遍,那么第一次第一个水池就被我们遍历完了,所有遍历过的地方都打上标记,防止二次遍历:
然后我们再接着第一行找没有被遍历过的水池:
找到之后我们就把它四周的没有被遍历过的水池全部遍历完:
然后回到第二行接着往下遍历,直到遍历到一个没有被遍历过的水池:
就把它周围全部遍历一遍:
code
两个 bfs()函数都可以 bfs写法
#include<bits/stdc++.h>
using namespace std;
#define x first
#define y second
const int N = 1010, M = N * N;;
typedef pair<int, int>PII;
int n, m,cnt;
char g[N][N];
bool st[N][N];
PII q[M];
int dx[8] = { 0,1,0,-1,1,1,-1,-1 };
int dy[8] = { 1,0,-1,0,1,-1,1,-1 };
void bfs(int x, int y)
{
int hh = 0, tt = 0;
q[0] = { x,y };
st[x][y] = true;
while (hh <= tt)
{
PII t = q[hh++];
for (int i = 0; i < 8; i++)
{
int tx = t.x + dx[i], ty = t.y + dy[i];
if (tx < 0 || tx >= n || ty < 0 || ty >= m || st[tx][ty]||g[tx][ty]=='.')continue;
q[++tt] = { tx,ty };
st[tx][ty] = true;
}
}
}
//void bfs(int x, int y) {
// q.push({ x, y });
// st[x][y] = true;
//
// while (!q.empty()) {
// PII t = q.front();
// q.pop();
//
// 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; // Skip the current cell
// if (i < 0 || i >= n || j < 0 || j >= m || st[i][j] || g[i][j] == '.') continue;
// q.push({ i, j });
// st[i][j] = true;
// }
// }
// }
//}
//void bfs(int x, int y) {
// q.push({ x, y });
// st[x][y] = true;
//
// while (!q.empty()) {
// PII t = q.front();
// q.pop();
//
// 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; // Skip the current cell
// if (i < 0 || i >= n || j < 0 || j >= m || st[i][j] || g[i][j] == '.') continue;
// q.push({ i, j });
// st[i][j] = true;
// }
// }
// }
//}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i++)cin >> g[i];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (g[i][j] == 'W' && !st[i][j])
{
bfs(i, j);
cnt++;
}
}
}
cout << cnt << endl;
return 0;
}
dfs写法
#include<bits/stdc++.h>
using namespace std;
const int N = 1010, M = N * N;;
int n, m,cnt;
char g[N][N];
bool st[N][N];
int dx[8] = { 0,1,0,-1,1,1,-1,-1 };
int dy[8] = { 1,0,-1,0,1,-1,1,-1 };
void dfs(int x, int y)
{
st[x][y] = true;
for (int i = 0; i < 8; i++)
{
int tx =x + dx[i], ty = y + dy[i];
if (tx < 0 || tx >= n || ty < 0 || ty >= m || st[tx][ty]||g[tx][ty]=='.')continue;
dfs(tx,ty);
}
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i++)cin >> g[i];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (g[i][j] == 'W' && !st[i][j])
{
dfs(i, j);
cnt++;
}
}
}
cout << cnt << endl;
return 0;
}