链接:http://poj.org/problem?id=2386
Lake Counting
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 24263 Accepted: 12246
Description
Due to recent rains, water has pooled in various places in Farmer John's field, which is represented by a rectangle of N x M (1 <= N <= 100; 1 <= M <= 100) squares. Each square contains either water ('W') or dry land ('.'). Farmer John would like to figure out how many ponds have formed in his field. A pond is a connected set of squares with water in them, where a square is considered adjacent to all eight of its neighbors.Given a diagram of Farmer John's field, determine how many ponds he has.
Input
* Line 1: Two space-separated integers: N and M* Lines 2..N+1: M characters per line representing one row of Farmer John's field. Each character is either 'W' or '.'. The characters do not have spaces between them.
Output
* Line 1: The number of ponds in Farmer John's field.
Sample Input
10 12W........WW.
.WWW.....WWW
....WW...WW.
.........WW.
.........W..
..W......W..
.W.W.....WW.
W.W.W.....W.
.W.W......W.
..W.......W.
Sample Output
3Hint
OUTPUT DETAILS:There are three ponds: one in the upper left, one in the lower left,and one along the right side.
Source
USACO 2004 November
大意——给你一个n*m的矩形网格。每一个格子里面要么是‘W’。要么是‘.’,它们分别表示水和旱地。
如今要你计算出有多少个池塘。
每一个池塘由若干个水组成,水能连接的方向有8个,仅仅要是能连接到的水都属于一个池塘。
思路——一个简单的DFS题。我们将所有的网格所有遍历一次,假如我们找到一个池塘的源头,就能够进行一次计数。而且将眼下找到的池塘源头标记为‘.’,那么下一次就不会反复訪问了。再从八个方向进行深搜,将能到达相邻的‘W’所有标记,以免反复訪问。这样最后得到的计数就是答案。
复杂度分析——时间复杂度:O(n*m),空间复杂度:O(n*m)
附上AC代码:
#include <iostream> #include <cstdio> #include <string> #include <cmath> #include <iomanip> #include <ctime> #include <climits> #include <cstdlib> #include <cstring> #include <algorithm> #include <queue> #include <vector> #include <set> #include <map> //#pragma comment(linker, "/STACK:102400000, 102400000") using namespace std; typedef unsigned int li; typedef long long ll; typedef unsigned long long ull; typedef long double ld; const double pi = acos(-1.0); const double e = exp(1.0); const double eps = 1e-8; const int maxn = 105; const int dir[8][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}, {-1, -1}, {1, -1}, {-1, 1}, {1, 1}}; // 8个方向 int n, m; // 矩形的行列 char mat[maxn][maxn]; // 矩形 void dfs(int x, int y); // 深度优先搜索 int main() { ios::sync_with_stdio(false); while (~scanf("%d%d", &n, &m)) { int cnt = 0; for (int i=0; i<n; i++) scanf("%s", mat[i]); for (int i=0; i<n; i++) for (int j=0; j<m; j++) if (mat[i][j] == 'W') { // 找到池塘源头,计数并深搜 cnt++; dfs(i, j); } printf("%d ", cnt); } return 0; } void dfs(int x, int y) { mat[x][y] = '.'; // 訪问过了。标记 for (int i=0; i<8; ++i) // 从八个方向找相邻的 if (x+dir[i][0]>=0 && x+dir[i][0]<n && y+dir[i][1]>=0 && y+dir[i][1]<m && mat[x+dir[i][0]][y+dir[i][1]]=='W') dfs(x+dir[i][0], y+dir[i][1]); // 找到相邻的,继续深搜 }