题意:在n*m的四联通矩阵上从起点走到终点,问是否能恰好在t秒到达,每个点最多走一次
思路:dfs即可,但会超时,需要用到奇偶性剪枝,即在dfs过程中当前点处的坐标到终点的曼哈顿距离和剩余的步数必须奇偶性一致
#include<bits/stdc++.h>
using namespace std;
char maze[8][8];
bool vis[8][8];
int dx[] = {0,1,0,-1};
int dy[] = {1,0,-1,0};
int n,m,t;
bool ans;
int ex, ey;
bool bound(int i,int j){
if(i <= 0 || i > n || j <= 0 || j > m) return false;
return true;
}
void dfs(int x, int y, int now_t){
if(maze[x][y] == 'D' && now_t == t){
ans = true;
return;
}
if(((abs(x-ex) + abs(y-ey)) & 1) != ( (t - now_t) & 1 ) ) return ;
for(int i = 0; i < 4; ++i){
int nx = x + dx[i];
int ny = y + dy[i];
if(bound(nx,ny) && maze[nx][ny] != 'X' && !vis[nx][ny]){
vis[nx][ny] = 1;
dfs(nx,ny,now_t+1);
if(ans) return ;
vis[nx][ny] = 0;
}
}
}
int main(){
while(scanf("%d%d%d",&n,&m,&t) == 3 && (n || m || t)){
for(int i = 1; i <= n; ++i){
scanf("%s",maze[i]+1);
}
int sx,sy;
for(int i = 1; i <= n; ++i){
for(int j = 1; j <= m; ++j){
if(maze[i][j] == 'S'){
sx = i, sy = j;
}
else if(maze[i][j] == 'D'){
ex = i, ey = j;
}
}
}
memset(vis,0,sizeof(vis));
vis[sx][sy] = 1;
ans = false;
dfs(sx,sy,0);
if(ans) printf("YES\n");
else printf("NO\n");
}
return 0;
}