问题模型
有一个矩形的房间里铺满正方形瓷砖。每块瓷砖涂成黑色或红色。一个人站在黑色的瓷砖上,从此出发,可以移动到四个相邻的瓷砖之一,但只能移动到黑色的瓷砖上。计算他通过重复上述移动所能经过的黑砖数。
示意图如下(画的有点丑(⊙﹏⊙)。)
输入
输入包含多个数据集。一个数据集开头行包括两个正整数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;
}