POJ 1979 Red and Black
阿新 • • 發佈:2020-11-16
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; //石磚數變為起先的初始狀態
}
}
}