Problem Description
给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方是障碍,她必须绕行,从迷宫的一个位置,只能走到与它相邻的4个位置中,当然在行走过程中,gloria不能走到迷宫外面去。令人头痛的是,gloria是个没什么方向感的人,因此,她在行走过程中,不能转太多弯了,否则她会晕倒的。我们假定给定的两个位置都是空地,初始时,gloria所面向的方向未定,她可以选择4个方向的任何一个出发,而不算成一次转弯。gloria能从一个位置走到另外一个位置吗?
Input
第1行为一个整数t (1 ≤ t ≤100),表示测试数据的个数,接下来为t组测试数据,每组测试数据中,
第1行为两个整数m, n (1 ≤ m, n ≤ 100),分别表示迷宫的行数和列数,接下来m行,每行包括n个字符,其中字符'.'表示该位置为空地,字符'*'表示该位置为障碍,输入数据中只有这两种字符,每组测试数据的最后一行为5个整数k, x1,y1, x2, y2 (1 ≤ k ≤ 10, 1 ≤ x1, x2≤ n, 1 ≤ y1, y2 ≤ m),其中k表示gloria最多能转的弯数,(x1,y1), (x2, y2)表示两个位置,其中x1,x2对应列,y1,y2对应行。
Output
每组测试数据对应为一行,若gloria能从一个位置走到另外一个位置,输出“yes”,否则输出“no”。
Sample Input
2
5 5
...**
*.**.
.....
.....
*....
1 1 1 1 3
5 5
...**
*.**.
.....
.....
*....
2 1 1 1 3
Sample Output
no
yes
算法思路:
1. 用一个二维矩阵构造迷宫,-1表示不可通行,0表示可以通行
2. 先将起始点的值填1,然后进行遍历,当遇到转角的时候将对应的值加上一填入二维矩阵中
3. 重复如此步骤。
#include "iostream"
using namespace std;
#define N 110
int iGroup[N][N];
const int step[5][2] = {{0,0},
{0,-1},//上
{0,1},//下
{-1,0},//左
{1,0}};//右
typedef struct
{
int x;
int y;
//int iDirection;
} Point;
Point ptResult[N*N];
int iGroupNum = 0;
int iClumn = 0;
int iRow = 0;
int i;
int DFS()
{
Point ptBegin;
Point ptEnd;
Point ptRoad;
Point ptHelp;
int iWheelNum;
cin >> iWheelNum;
cin >> ptBegin.x >> ptBegin.y;
cin >> ptEnd.x >> ptEnd.y;
// int iOldDirection = 0;
// int iCurDirection = 0;//1表示上,2表示下,3表示左,4表示右
int iHead = 0;
int iTail = 1;
// ptBegin.iDirection = 0;
// ptEnd.iDirection = 0;
if (ptBegin.x == ptEnd.x && ptBegin.y == ptEnd.y)
{
return 1;
}
if (iGroup[ptBegin.y][ptBegin.x] == -1 || iGroup[ptEnd.y][ptEnd.x] == -1)
{
return 0;
}
//2. 进行遍历查找符合要求的路径
//Point *ptResult = (Point*)malloc(sizeof(Point) * iRow * iClumn);
//Point ptVisited[10] = {0};
ptResult[1] = ptBegin;
iGroup[ptBegin.y][ptBegin.x] = 1;
while (iHead < iTail)
{
ptRoad = ptResult[++iHead];
if (iGroup[ptRoad.y][ptRoad.x] - 1 > iWheelNum)
{
return 0;
}
// iOldDirection = ptResult[iHead].iDirection;
for (int i = 1; i < 5; ++i)
{
ptHelp = ptRoad;
do{
ptHelp.x += step[i][0];
ptHelp.y += step[i][1];
//iCurDirection = i;
if (ptHelp.x == ptEnd.x && ptHelp.y == ptEnd.y)
{
return 1;
}
if (!iGroup[ptHelp.y][ptHelp.x])
{
ptResult[++iTail] = ptHelp;
iGroup[ptHelp.y][ptHelp.x] = iGroup[ptRoad.y][ptRoad.x] + 1;
}
}while (iGroup[ptHelp.y][ptHelp.x] != -1);
}
}
//释放空间
//free(ptResult);
return 0;
}
void MakeMaze()
{
char c;
cin >> iRow >> iClumn;
//动态开辟空间
// int **iGroup = (int **)malloc(sizeof(int*) * (iRow + 2));
// for (i = 0; i < iClumn + 2; ++i)
// {
// iGroup[i] = (int *)malloc(sizeof(int) * (iClumn + 2));
// }
//
//1. 构建迷宫
// for (i = 0; i < iRow + 2; ++i)
// {
// iGroup[0][i] = -1;
// iGroup[iRow + 1][i] = -1;
// }
// for (i = 0; i < iClumn + 2; ++i)
// {
// iGroup[i][0] = -1;
// iGroup[i][iClumn + 1] = -1;
// }
for (i = 0; i < N; ++i )
{
for (int j = 0; j < N; ++j)
{
iGroup[i][j] = -1;
}
}
for (i = 1; i < iRow + 1; ++i)
{
for (int j = 1; j < iClumn + 1; ++j)
{
cin >> c;
if ('.' == c)
{
iGroup[i][j] = 0;
}else if ('*' == c)
{
iGroup[i][j] = -1;
}else
{
//cout << "error!" << endl;
//exit(1);
}
}
}
}
int main()
{
//读入数据
cin >> iGroupNum;
while (0 != iGroupNum--)
{
MakeMaze();
if(DFS())
{
cout << "yes" << endl;
}
else{
cout << "no" << endl;
}
}
return 1;
}