题目描述
张晨乐在一个古老的迷宫中发现了一个手机,这个手机深深地吸引了他。
然而,当他拾起手机,迷宫开始摇晃,张晨乐能感觉到地面下沉。他意识到:这个手机只是一个诱饵!于是,他不顾一切地试图冲出这个迷宫。
迷宫是一个大小为N*M的矩形,有一扇门,一开始,门是关闭的,并在第T秒打开一瞬间(小于1秒的时间)。因此,张晨乐必须刚好在第T秒钟到达门口。
每一秒,他都可以向上,下,左,右四个相邻的位置中的任意一个移动。一旦他进入一个新的地方,这个地方的地面就会开始下沉,并在下一秒消失。因此,他不能在一个地方停留超过一秒钟,也不能再进入曾经走过的地方。
请问,可怜的张晨乐能够逃出迷宫吗?
输入
输入由多个测试用例组成。
每个测试用例的第一行包含三个整数N,M和T(1 <N,M <7; 0 <T <50),分别表示迷宫的大小和门打开的时间。
接下来的N行给出迷宫布局,每行包含M个字符。
每个字符含义如下:
'X':不能进入的墙
'S':起点
'D':门
'.':可以行走的地方
输入以三个0结束,这个测试用例不被处理。
输出
对于每组测试数据,如果张晨乐能够逃出迷宫,则请输出“YES”,否则,请输出“NO”。每组数据输出占一行。
样例输入 Copy
4 4 5 S.X. ..X. ..XD .... 3 4 5 S.X. ..X. ...D 0 0 0
样例输出 Copy
NO YES
#include<iostream>
using namespace std;
int vis[9][9] = { 0 };
char map[9][9];
int mov[4][2] = { {1,0},{0,1},{-1,0},{0,-1} };
int row, col, Time;
int wall_numbers;
int start_x, start_y;
int end_x, end_y;
int flag = 0;
void dfs(int start_x, int start_y, int steps) {
if (start_x<1 || start_x>row || start_y<1 || start_y>col)return;
if (map[start_x][start_y] == 'X')return;
if (start_x == end_x && start_y == end_y && steps == Time) {
flag = 1;
return;
}
//获取下一个点的位置
int next_x, next_y;
for (int i = 0; i < 4; i++) {
next_x = start_x + mov[i][0];
next_y = start_y + mov[i][1];
if (vis[next_x][next_y])continue;
vis[next_x][next_y] = 1;
dfs(next_x, next_y, steps + 1);
vis[next_x][next_y] = 0;
}
}
int main()
{
while (cin >> row >> col >> Time) {
if (row == 0 && col == 0 && Time == 0)
break;
//初始化
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
vis[i][j] = 0;
wall_numbers = 0;
flag = 0;
getchar();
//读入地图数据
for (int i = 1; i <= row; i++) {
for (int j = 1; j <= col; j++) {
scanf("%c", &map[i][j]);
}
getchar();
}
//寻找起始点,终点,统计墙面数量
for(int i = 1;i<=row;i++)
for (int j = 1; j <= col; j++) {
if (map[i][j] == 'S') {
start_x = i;
start_y = j;
}
if (map[i][j] == 'X') {
wall_numbers++;
}
if (map[i][j] == 'D') {
end_x = i;
end_y = j;
}
}
//奇偶性剪枝
if ((start_x + start_y) % 2 && (end_x + end_y) % 2) {
if (Time % 2) {
cout << "NO" << endl;
continue;
}
}
if ((start_x + start_y) % 2 == 0 && (end_x + end_y) % 2 == 0) {
if (Time % 2) {
cout << "NO" << endl;
continue;
}
}
if ((start_x + start_y) % 2 == 0 && (end_x + end_y) % 2) {
if (!(Time % 2)) {
cout << "NO" << endl;
continue;
}
}
if ((start_x + start_y) % 2 && (end_x + end_y) % 2 == 0) {
if (!(Time % 2)) {
cout << "NO" << endl;
continue;
}
}
if (row * col - wall_numbers <= Time) {
cout << "NO" << endl;
continue;
}
//DFS算法
vis[start_x][start_y] = 1;
dfs(start_x, start_y, 0);
if (flag)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}