题目链接: hdu 1010 Tempter of the Bone
题目大意: 给一个迷宫,小狗要从大门出去,但是大门只有在T时刻才会开门所以小狗只有在T时刻到达门口才算成功,而且每秒钟小狗可以上下左右走一个方块,但是方块在下一秒就会消失,图中S代表小狗的起始位置,D代表大门,X是障碍物。问小狗能否成功逃出迷宫。
题解思路: 直接用DFS就可以了,但是发现如果不进行任何剪枝的话,就会超时,所以这里可以用奇偶剪枝,通过D和S的位置可以算出小狗出去的最短路径,根据这个最短路径和给定的时间T的奇偶性可以直接判断是否可以出去。
代码如下:
#include<bits/stdc++.h>
using namespace std;
int m, n, t;
#define check(x, y) (x < m && x >= 0 && y < n && y >= 0)
int sx, sy;
int ex, ey;
char dt[10][10];
int d[4][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
int vis[10][10];
bool dfs(int x, int y, int step)
{
if(dt[x][y] == 'D' && step == t){
return true;
}
else{
for(int i = 0; i < 4; i++){
int dx = x + d[i][0];
int dy = y + d[i][1];
if(check(dx, dy) && !vis[dx][dy] && dt[dx][dy] != 'X'){
vis[dx][dy] = 1;
if(dfs(dx, dy, step + 1)){
return true;
}
else{
vis[dx][dy] = 0;
}
}
}
}
return false;
}
int main()
{
while(1){
cin >> m >> n >> t;
if(m == 0 && n == 0 && t == 0){
break;
}
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
cin >> dt[i][j];
if(dt[i][j] == 'S'){
sx = i;
sy = j;
}
if(dt[i][j] == 'D'){
ex = i;
ey = j;
}
}
}
if((abs(ex - sx) + abs(ey - sy) + t) % 2 == 1){
cout << "NO" << endl;
}
else{
memset(vis, 0, sizeof(vis));
vis[sx][sy] = 1;
if(dfs(sx, sy, 0)){
cout << "YES" << endl;
}
else{
cout << "NO" << endl;
}
}
}
return 0;
}