链接http://acm.hdu.edu.cn/diy/contest_showproblem.php?pid=1012&cid=34750
Problem Description
The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it up, the maze began to shake, and the doggie could feel the ground sinking. He realized that the bone was a trap, and he tried desperately to get out of this maze.
The maze was a rectangle with sizes N by M. There was a door in the maze. At the beginning, the door was closed and it would open at the T-th second for a short period of time (less than 1 second). Therefore the doggie had to arrive at the door on exactly the T-th second. In every second, he could move one block to one of the upper, lower, left and right neighboring blocks. Once he entered a block, the ground of this block would start to sink and disappear in the next second. He could not stay at one block for more than one second, nor could he move into a visited block. Can the poor doggie survive? Please help him.
Input
The input consists of multiple test cases. The first line of each test case contains three integers N, M, and T (1 < N, M < 7; 0 < T < 50), which denote the sizes of the maze and the time at which the door will open, respectively. The next N lines give the maze layout, with each line containing M characters. A character is one of the following:
'X': a block of wall, which the doggie cannot enter;
'S': the start point of the doggie;
'D': the Door; or
'.': an empty block.
The input is terminated with three 0's. This test case is not to be processed.
Output
For each test case, print in one line "YES" if the doggie can survive, or "NO" otherwise.
Sample Input
4 4 5
S.X.
..X.
..XD
....
3 4 5
S.X.
..X.
...D
0 0 0
Sample Output
NO
YES
题意是给一个n*m的地图,T为出口开启的时间,要在T这个时间点到达出口,否则失败。
最开始没看懂题意,以为是T秒内到达出口就可以,用BFS写了,题目中说了在某一位置
不能停留超过一秒,所以最短的路径不一定是正好T秒到的路径,用DFS来做。需要用到
奇偶性剪枝,直接深搜时间超限。
题目说了每个位置只能待一秒, 从起点到终点, 需要走的距离即为abs(sx - ex) + abs(sy - ey), 如果在T跟这个要求的时间
奇偶都不同, 肯定没法到终点(毕竟每次不能停即一秒一步)。
#include<iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;
int dir[4][2] = { 0, 1, 0, -1, 1, 0, -1, 0 };
char map[10][10];
int vis[10][10];
int flag = 0;
int n, m, T, sx, sy, ex, ey;
void dfs(int x, int y, int t){
if ((abs(sx - ex) + abs(sy - ey)) % 2 != T % 2) //剪枝
return;
if (flag)return; //已经到达终点
if (t > T)return; //时间超出T
if (x == ex&&y == ey&&t == T)//如果在T秒到达终点
{
flag = 1;
return;
}
for (int i = 0; i < 4; i++)
{
int xx = x + dir[i][0];
int yy = y + dir[i][1];
if (xx < n&&xx >= 0 && yy < m&&yy >= 0 && !vis[xx][yy] && map[xx][yy] != 'X') //判断是否能走该步
vis[xx][yy] = 1, dfs(xx, yy, t + 1), vis[xx][yy] = 0;
}
}
int main(){
while (cin >> n >> m >> T && (m || n || T)){
flag = 0;
memset(vis, 0, sizeof(vis));
for (int i = 0; i < n; i++)
cin >> map[i];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
{
if (map[i][j] == 'S')sx = i, sy = j; //找到起点坐标
if (map[i][j] == 'D')ex = i, ey = j; //终点坐标
}
vis[sx][sy] = 1; //对起始位置标记
dfs(sx, sy, 0);
if (flag)cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}