宣传一下算法提高课整理 <—
CSDN个人主页:更好的阅读体验 <—
题目传送门点这里
题目描述
农夫约翰有一片 N∗M 的矩形土地。
最近,由于降雨的原因,部分土地被水淹没了。
现在用一个字符矩阵来表示他的土地。
每个单元格内,如果包含雨水,则用”W”表示,如果不含雨水,则用”.”表示。
现在,约翰想知道他的土地中形成了多少片池塘。
每组相连的积水单元格集合可以看作是一片池塘。
每个单元格视为与其上、下、左、右、左上、右上、左下、右下八个邻近单元格相连。
请你输出共有多少片池塘,即矩阵中共有多少片相连的”W”块。
输入格式
第一行包含两个整数 N 和 M。
接下来 N 行,每行包含 M 个字符,字符为”W”或”.”,用以表示矩形土地的积水状况,字符之间没有空格。
输出格式
输出一个整数,表示池塘数目。
数据范围
1 ≤ N , M ≤ 1000 1≤N,M≤1000 1≤N,M≤1000
样例输入
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
思路
Flood Fill算法,好高大上的名字!
但它其实就是BFS
用途: 求一个图形中连通块的个数
步骤:
- 找到任意一个连通块包含的点,这步可以直接遍历找
- 在这个连通块上跑BFS,把这个连通块的所有点都打上标记(当然,把
W
改成.
也是可以的) - 继续找连通块,重复步骤1和2,直到所有连通块都被遍历过
- 找到一个连通块就给答案加一,输出答案即可
注意:
- 图里面的字符大小写和全半角不要搞混
- 输入的时候不要按字符输入,不然会输进去
\n
和space
这些奇奇怪怪的东西,导致WA - 可以放心用STL的queue,不会超时
算法时间复杂度
BFS差不多会把所有点跑一遍,因此时间复杂度差不多是 O ( n m ) O(nm) O(nm)
AC Code
C + + C++ C++
#include <iostream>
#include <queue>
using namespace std;
typedef pair<int, int> PII;
const int N = 1010;
int dx[] = {1, 1, 1, 0, -1, -1, -1, 0};
int dy[] = {-1, 0, 1, 1, 1, 0, -1, -1};
int n, m;
char a[N][N];
int res;
void bfs(int x, int y)
{
queue<PII> q;
q.push({x, y});
while (q.size())
{
auto t = q.front();
q.pop();
int px = t.first, py = t.second;
for (int i = 0; i < 8; i ++ )
{
int xx = px + dx[i], yy = py + dy[i];
if (xx >= 0 && xx < n && yy >= 0 && yy < m && a[xx][yy] == 'W')
{
a[xx][yy] = '.';
q.push({xx, yy});
}
}
}
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i ++ )
scanf("%s", &a[i]);
for (int i = 0; i < n; i ++ )
for (int j = 0; j < m; j ++ )
if (a[i][j] == 'W')
{
bfs(i, j);
res ++ ;
}
printf("%d\n", res);
return 0;
}
最后,如果觉得对您有帮助的话,点个赞再走吧!