1. 程式人生 > 實用技巧 >POJ 1979 Red and Black

POJ 1979 Red and Black

Red and Black

原題目如下:

有一個長方形的房間,覆蓋了正方形的磁磚。每塊磁磚的顏色,要麼是紅色,要麼是黑色。一名男子站在一塊黑色的磁磚上。他可以從一塊磁磚移至相鄰四塊磁磚中的某一塊。但是,他不允許在紅色磁磚上移動,他只允許在黑色磁磚上移動。

編寫一個程式,使得他允許重複上述的移動,判斷他所能到達的黑色磁磚的數量。


輸入:

輸入由多個數據集組成。資料集的起始行包含了兩個正整數 W 和 H;W 和 H 分別是 x- 和 y- 方向的磁磚數量。W 和 H 不超過 20 。

在資料集中,還有 H 行,每行包含了 W 個字元。每個字元按如下方式表示一塊磁磚的顏色。

'.' - 一塊黑色的磁磚

'#' - 一塊紅色的磁磚

'@' - 一名男子,站在一塊黑色磁磚上 (在一個數據集中,恰好出現一次)

以包含兩個 0 的一行,表示輸入結束。


輸出:

對於每個資料集,程式應當輸出一行,包含他從初始磁磚所能抵達的磁磚數量 (包括初始磁磚自身)。


示例輸入:

6 9

....#.

.....#

......

......

......

......

......

#@...#

.#..#.

11 9

.#.........

.#.#######.

.#.#.....#.

.#.#.###.#.

.#.#..@#.#.

.#.#####.#.

.#.......#.

.#########.

...........

11 6

..#..#..#..

..#..#..#..

..#..#..###

..#..#..#@.

..#..#..#..

..#..#..#..

7 7

..#.#..

..#.#..

###.###

...@...

###.###

..#.#..

..#.#..

0 0


示例輸出

45

59

6

13


解題思路

這道題是一道非常經典的dfs問題,這題的思路就是:從@處進行出發,去遍歷每一個.的頂點並計數就好。唯一需要注意的是:在每個示例時候,我們都需要將Count(計數變數)進行初始化為1。因為當前@節點所處的位置也是要數的磚塊。並且在每次遍歷.時,我們都需要將.更改為#。以免之前遍歷過得節點被重複遍歷。導致之後的結果不正確!


程式碼如下:

#include <iostream>
#include <cstdio>
using namespace std;
char Graph[20][20];             //代表房間
int w, h;                       //代表房間的寬度與高度
int Count = 1;                  //代表瓷磚的個數(包括初始瓷磚自身)
void dfs(int x,int y);           //代表進行深度優先搜尋的函式

void dfs(int x, int y)
{
	int i, j;
	int movex, movey;       //代表移動之後的座標
	Graph[x][y] = '#';     //將當前所在的位置設定為#號,以免重複遍歷到
	for (i = -1; i <= 1; i++)
	{
		for (j = -1; j <= 1; j++)
		{
			if (j == 0 || i == 0)   //代表移動的方向為(-1,0)(1,0) (0,-1)(0,1)
			{
				movex = x + i;
				movey = y + j;
				if (movex >= 0 && movex < h && movey >= 0 && movey < w && Graph[movex][movey] == '.')
				{
					Count++;    //代表找到了下一個瓷磚
					dfs(movex, movey);   //往下一個瓷磚進行深度優先遍歷
				}

			}
		}
	}
}
int main()
{
	int i, j;
	char x;
	while (scanf("%d %d", &w,&h) != EOF)
	{
		if (h == 0 && w == 0)
		{
			return 0;
		}
		else
		{
			for (i = 0; i < h; i++)
			{
				for (j = 0; j < w; j++)
				{
					cin >> x;
					Graph[i][j] = x;
				}
			}
			for (i = 0; i < h; i++)
			{
				for (j = 0; j < w; j++)
				{
					if (Graph[i][j] == '@')
					{
						dfs(i, j);    //從起點處開始深度優先搜尋
					}
				}
			}
			printf("%d\n", Count);
			Count = 1;   //石磚數變為起先的初始狀態
		}
	}
}