逃离迷宫
问题描述:
给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方是障碍,她必须绕行,从迷宫的一个位置,只能走到与它相邻的4个位置中,当然在行走过程中,gloria不能走到迷宫外面去。令人头痛的是,gloria是个没什么方向感的人,因此,她在行走过程中,不能转太多弯了,否则她会晕倒的。我们假定给定的两个位置都是空地,初始时,gloria所面向的方向未定,她可以选择4个方向的任何一个出发,而不算成一次转弯。gloria能从一个位置走到另外一个位置吗?
输入:
第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对应行。
输出:
每组测试数据对应为一行,若gloria能从一个位置走到另外一个位置,输出“yes”,否则输出“no”。
Sample Input
5 5
…**
.*.
…..
…..
*….
1 1 1 1 3
Sample Output
no
Sample Input
5 5
…**
.*.
…..
…..
*….
2 1 1 1 3
Sample Output
yes
代码
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#define MAX 999999
char Map[100][100];
int turn[100][100];
int n, m;
int x2,y2,k; //终点坐标以及最多能turn的次数
int flag;//记录是否可以的标识
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
void DFS(int x,int y,int dir)
{
int i,xx,yy;
if(x == x2 && y == y2 && turn[x][y] <= k) {//成功的条件
flag = 1;
return ;
}
if(turn[x][y] > k) {//不行的时候返回条件
return ;
}
for(i = 0;i < 4; i++) {//四个方向
xx = x + dx[i];
yy = y + dy[i];
if(xx <= 0 || yy <= 0 || xx > m || yy > n || Map[xx][yy] == '*') { //超出Map范围即是不能走
continue;
}
if(turn[xx][yy] < turn[x][y]) {//turn[xx][yy] < turn[x][y]成立说明,xx,yy已经走过!这也是为啥main函数初始化turn为MAX
continue; //思考为什么这里 = 不进行剪枝!
}
//如果从(x,y)走一步到(xx,yy)需要转一次话,并且转过之后turn[x][y]+1依然比turn[xx][yy]大的话,也不符合
if(dir != -1 && i != dir && turn[xx][yy] < turn[x][y]+1) {
continue;//剪枝是搜索最最难的地方,也是核心点
}
if(dir != -1 && i != dir) {
turn[xx][yy]=turn[x][y]+1;//转弯,更新turn
}
else {
turn[xx][yy] = turn[x][y];
}
Map[xx][yy] = '*'; //如果这里能走,就把这里变成不能走,然后再从这里开始递归,其实就是起到vis[][] 的作用,会用vis的话就不用追究了
DFS(xx,yy,i);
Map[xx][yy] = '.'; //这里再变成'.',回溯!
if(1 == flag) {
return ;
}
}
}
int main()
{
int x1, y1;
scanf("%d%d", &m,&n);
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
scanf(" %c", &Map[i][j]);
turn[i][j] = MAX;//用于记录转弯次数
}
}
scanf("%d%d%d%d%d", &k, &y1, &x1, &y2, &x2);
flag = 0;
turn[x1][y1] = 0;
DFS(x1, y1, -1);
if (1 == flag) {
printf("yes\n");
}
else {
printf("no\n");
}
return 0;
}
有不懂的 ,欢迎留言交流~