ACM 训练日志记录 · 思考 · 成长 提交 / 修改记录
廖夏 / 题目列表训练档案
导出

P1596 [USACO10OCT] Lake Counting S

来源:洛谷 ★ 1000

本题活力0.40按难度、完成结果与训练证据估算

算法如山行则将至

题目描述

[USACO10OCT] Lake Counting S

题目描述

由于最近的降雨,水在农夫约翰的田地里积聚了。田地可以表示为一个 $N \times M$ 的矩形($1 \leq N \leq 100$;$1 \leq M \leq 100$)。每个方格中要么是水(W),要么是干地(.)。农夫约翰想要弄清楚他的田地里形成了多少个水塘。一个水塘是由连通的水方格组成的,其中一个方格被认为与它的八个邻居相邻。给定农夫约翰田地的示意图,确定他有多少个水塘。

输入格式

第 $1$ 行:两个用空格分隔的整数:$N$ 和 $M$。

第 $2$ 行到第 $N+1$ 行:每行 $M$ 个字符,表示农夫约翰田地的一行。

每个字符要么是 W,要么是 .。

字符之间没有空格。

输出格式

第 $1$ 行:农夫约翰田地中的水塘数量。

说明/提示

输出详情:共有三个水塘:一个在左上角,一个在左下角,还有一个沿着右侧。

(由 ChatGPT 4o 翻译)

样例 1

输入:

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

代码

#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 105;
bool mp[MAXN][MAXN];
bool w[MAXN][MAXN];
int m, n, ans;
int dx[] = {0, 0, 1, 1, -1, -1, 1, -1};
int dy[] = {1, -1, 1, -1, 1, -1, 0, 0};
void dfs(int x, int y){
	w[x][y] = 1;
	for (int k = 0; k < 8; k++){
		int nx = x + dx[k], ny = y + dy[k];
		if (nx >= 1 && ny >= 1 && nx <= n && ny <= m && mp[nx][ny] && !w[nx][ny])
			dfs(nx, ny);
	}
}
int main(){
	cin >> n >> m;
	for (int i = 1; i <= n; i++){
		for (int j = 1; j <= m; j++){
			char c;
			cin >> c;
			if (c == 'W') mp[i][j] = 1;
		}
	}
	for (int i = 1; i <= n; i++){
		for (int j = 1; j <= m; j++){
			if (mp[i][j] && !w[i][j]) {
				ans++;
				dfs(i, j);
			}
		}
	}
	cout << ans;
	return 0;
}