(ZOJ2001)判断小狗能否跑出迷宫,即在t时刻能否刚好到达出口。D代表门,W代表墙,S代表小狗。迷宫为N*M
#include <stdio.h>
#include <math.h>
char map[9][9];
int n,m,t;
int di,dj;
bool escape; //逃脱标志
int dir[4][2] = {{-1,0},{1,0},{0,1},{0,-1}};
void dfs (int si,int sj,int cnt) {
if (si>n ||si<=0 ||sj>m ||sj<=0)
return;
if (si==di && sj==dj && cnt==t) {
escape = 1;
return;
}
//奇偶剪枝:计算剩余时间,<0则不够,时间充裕,绕路必为偶
int temp = t-cnt-abs(si-di)-abs(sj-dj);
if (temp < 0 || temp%2)
return;
for(int i = 0;i < 4;i++) {
if(map[si+dir[i][0]][sj+dir[i][1]] != 'X') {
map[si+dir[i][0]][sj+dir[i][1]] = 'X';
dfs(si+dir[i][0],sj+dir[i][1],cnt+1);
if (escape)
return;
//后退,恢复现场
map[si+dir[i][0]][sj+dir[i][1]] = '.';
}
}
//均未搜索到,则整个分支返回
return;
}
int main () {
int si,sj;
while (scanf ("%d %d %d",&n,&m,&t)) {
if (n == 0 && m == 0 && t == 0)
break;//结束测试
getchar();
/*char temp;
scanf("%c",temp);回收换行符
*/
int wall = 0;
//范围1—n,从0开始搜索中会越界
for (int i = 1;i <= n;i++) {
for (int j = 1;j <=m;j++) {
scanf ("%c",&map[i][j]);
if (map[i][j] == 'S') {
si = i;sj = j;
} else if (map[i][j] == 'D') {
di = i;dj = j;
} else if (map[i][j] == 'W')
wall++;
}
getchar();
}
//搜索前剪枝
if ((n*m - wall) <= t) {
printf ("NO\n");
continue;
}
escape = 0;
map[si][sj] = 'X';
dfs(si,sj,0);
if (escape)
printf ("YES\n");
else printf ("NO\n");
}
return 0;
}
这篇博客探讨了如何使用深度优先搜索(DFS)算法解决ZOJ2001题,即判断小狗在给定时间t内是否能通过N*M的迷宫到达出口。题目中,D表示门,W表示墙,S表示小狗。
932

被折叠的 条评论
为什么被折叠?



