問題模型
有一個矩形的房間裏鋪滿正方形瓷磚。每塊瓷磚塗成黑色或紅色。一個人站在黑色的瓷磚上,從此出發,可以移動到四個相鄰的瓷磚之一,但只能移動到黑色的瓷磚上。計算他通過重複上述移動所能經過的黑磚數。
示意圖如下(畫的有點醜(⊙﹏⊙)。)
輸入
輸入包含多個數據集。一個數據集開頭行包括兩個正整數W和H,W和H分別表示矩陣的列數和行數,切不超過20.
每個數據集有H行,其中每行包含W個字符。每個字符的含義如下所示。
‘R’——紅磚
‘B’——黑磚
‘@’——人(每個數據集僅出現一次)
兩個0表示結束
輸出
分析
使用遞歸方法求解經過的瓷磚數。設n,m分別爲矩形的行數和列數;sum爲經過的瓷磚數;map爲瓷磚圖,其中map[i][j]爲座標i , j的字符;visited爲訪問標誌,visited[i][j]表示已經過座標(i,j);遞歸函數爲search(i,j).其中:
狀態:當前位置(i,j),遞歸前爲出發位置。
邊界條件:若當前座標在地圖外(i<0 || i>=n || j<0 || j>=n)或不可通行(map[i][j] ==’R’),或已經訪問過(visited[i][j] ==true),則回溯;否則將座標(i,j)設訪問標誌(visited[i][j] = true),經過的瓷磚數sum++,繼續遞歸。
搜索範圍:遞歸當前座標(i,j)的四個相鄰點(i-1,j),(i+1,j),(i,j-1),(i,j+1).
編碼
#include "stdafx.h"
#include <iostream>
using namespace std;
// R 紅磚 B 黑磚 @人
const int MAX_ROW = 20, MAX_COLUMN = 20;
int sum, m, n; //經過的瓷磚數 行數 列數
char map[MAX_ROW][MAX_COLUMN];
bool visited[MAX_ROW][MAX_COLUMN]; //記錄訪問標誌的數組
//遞歸計算從(row,col)出發經過的瓷磚數
void search(int row, int col)
{
//邊界條件 座標在地圖外,不可通行,已經訪問過 則回溯
if (row < 0 || row >= n || col < 0 || col >= n || map[row][col] == 'R' || visited[row][col])
return;
visited[row][col] = true; //設置當前座標的標誌位
++sum; //經過的瓷磚數+1
//遞歸遍歷當前座標的四個相鄰點
search(row-1, col);
search(row+1 , col);
search(row , col-1);
search(row, col+1);
}
int _tmain(int argc, _TCHAR* argv[]){
cin >> m >> n; //輸入行數和列數
while (m || n)
{
int row, col;
for (int i = 0; i < n; i++)
{
cin>> map[i]; //輸入當前行的數據集
for (int j = 0; j < m; j++)
{
if (map[i][j] == '@')
{
row = i;
col = j;
}
}
}
memset(visited,false,sizeof(visited));
sum = 0;
search(row, col);
cout << sum << endl;
cin >> m >> n;
}
return 0;
}