难度:3
算法:搜索dfs
题目大意:一只狗要吃骨头,结果进入了一个迷宫陷阱,迷宫里每走过一个地板费时一秒,该地板就会在下一秒塌陷,所以你不能在该地板上逗留。迷宫里面有一个门,只能在特定的某一秒才能打开,让狗逃出去。现在题目告诉你迷宫的大小和门打开的时间,问你狗可不可以逃出去,可以就输出YES,否则NO。
这道题考虑搜索的减枝。
减枝的条件是:
1.如果可走地板数目小于给定的时间,绝对不可能得救。
2.狗走到门的时间必须和题目给定的时间是同奇同偶的,否则也不能在指定的那秒到达门,也不可能得救
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 10;
char ch[maxn][maxn];
int n , m , t;
bool vis[maxn][maxn];
int sx , sy , ex , ey;
int dir[4][2] = {1,0,-1,0,0,1,0,-1};
bool inmap(int x,int y) {
return x >= 0 && x < n && y >= 0 && y < m;
}
bool check1(int x,int y,int ct) {
return abs(x-ex) + abs(y-ey) + ct <= t;
}
bool check2(int x,int y,int ct) {
return (abs(x-ex) + abs(y-ey)) % 2 == (t - ct) % 2;
}
bool init() {
for(int i=0;i<n;i++) scanf("%s" , ch[i]);
memset(vis , false , sizeof(vis));
for(int i=0;i<n;i++)
for(int j=0;j<m;j++) {
if(ch[i][j] == 'S') sx = i , sy = j;
if(ch[i][j] == 'D') ex = i , ey = j;
}
}
bool dfs(int x,int y,int ct) {
if(ct > t) return false;
if(ct == t) {
if(ch[x][y] == 'D') return true;
return false;
}
if(!check1(x , y , ct)) return false;
if(!check2(x , y , ct)) return false;
vis[x][y] = true;
for(int i=0;i<4;i++) {
int xx = x + dir[i][0];
int yy = y + dir[i][1];
if(!inmap(xx , yy) || vis[xx][yy] || ch[xx][yy] == 'X') continue;
if(dfs(xx , yy , ct+1)) return true;
}
vis[x][y] = false;
return false;
}
int main() {
while(~scanf("%d%d%d" , &n,&m,&t) && n+m+t) {
init();
if(!dfs(sx , sy , 0)) puts("NO");
else puts("YES");
}
return 0;
}