1. 程式人生 > 實用技巧 >POJ 2386 Lake Counting

POJ 2386 Lake Counting

Lake Counting(POJ 2386)

原題目如下:

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 12

W........WW.

.WWW.....WWW

....WW...WW.

.........WW.

.........W..

..W......W..

.W.W.....WW.

W.W.W.....W.

.W.W......W.

..W.......W.

Sample Output


3


解題思路:

這道題是一道非常經典的深度優先演算法題目,具體思路為:我們先任意找到一個W,從那個W開始進行遍歷,在遍歷時尋找下一個W,直到沒有W為止,算作一個水坑。並且,當我們遍歷到W時,我們需要將這個W改為. 目的是為了不重複進行遍歷。注意,在每一次示例之後,都要清一次count。不然的話上一個示例的水坑數將導致這一次的水坑數不正確。(其實,這道題的基本思想就是圖的遍歷)(實在不懂的話,閱讀一下程式碼再結合例項就會明白)


程式碼如下:

#include <iostream>
#include <cstdio>
using namespace std;
char graph[100][100];   
int n,m;
pair<int, int> Move[3][3];   //定義一個pair型別的陣列,代表能移動的方向(需要用field陣列構造)(分別對應著九個移動的方向)
int field[3] = { -1,0,1 };   
void dfs(int x, int y);    //代表進行深度優先搜尋的函式

void dfs(int x, int y)
{
	int movex, movey;          //定義移動後的x,y座標
	int k, l;
	graph[x][y] = '.';   //將當前所在的位置設定為沒有積水
	for (k = 0; k < 3; k++)
	{
		for (l = 0; l < 3; l++)
		{
			movex = x + Move[k][l].first;
			movey = y + Move[k][l].second;
			if (movex >= 0 &&  movex < n && movey >= 0 && movey < m && graph[movex][movey] == 'W')    //當在圖中移動時,x的移動,代表了座標向上或下移動了多少。y的移動,代表了座標向左或向右移動了多少
			{
				dfs(movex, movey);
			}
		}
	}
	
}
int main()
{
	int i, j;
	int count=0;
	while (scanf("%d %d",&n,&m)!=EOF)
	{
		for (i = 0; i < n; i++)
		{
			for (j = 0; j < m; j++)
			{
				cin >> graph[i][j];
			}
		}
		for (i = 0; i < 3; i++)
		{
			for (j = 0; j < 3; j++)
			{
				Move[i][j] = make_pair(field[i], field[j]);
			}
		}
		for (i = 0; i < n; i++)
		{
			for (j = 0; j < m; j++)
			{
				if (graph[i][j] == 'W')   //再圖中進行搜尋,看有沒有值為W的節點,如果有,從這個節點開始遍歷
				{
					dfs(i, j);     //對這個節點以及跟這個節點的所有聯通節點,進行深度優先搜尋
					count++;       //一次深度優先搜尋之後,水坑數就+1(這個地方不懂的話,就參考上面的輸入例項自己思考一下把)
				}
			}
		}
		printf("%d\n", count);
		count = 0;
	}
}