题目意思: 一只吉娃娃去迷宫捡骨头, 捡到骨头后发现是一个陷阱, 然后就想逃出迷宫;迷宫是N*M 规格的, 迷宫只有一道门且 只在第 T 秒钟开一会儿(少于1秒) 也就是说只在【 t, t+1) 秒开。 这只吉娃娃只能向 上下左右四个方向移动, 每次只能移动 一个格子的距离, 每当这只吉娃娃移动到一个格子上后, 这只格子就要开始下沉(也就是说, 这只吉娃娃不能在一个格子中待上超过一秒钟) 请问这只吉娃娃可不可以逃出迷宫;
迷宫是 N * M 的规格, 其中
'X': 是墙,吉娃娃不能走
'S': 吉娃娃刚开始站的地方
'D': 门
'.': 空地 吉娃娃可以走
题目分析: 只要在规定时间恰好从起点到达终点就可以了, 数据规模也不大, dfs 可以搞:
这里不用判断最短时间什么的直接dfs就可以了
我的代码:
//dfs
#include<bits/stdc++.h> //c11的头文件, 包含所有头文件
using namespace std;
const int maxn = 10; //数据规模
char a[maxn][maxn]; //保存迷宫地图的数组
int vis[maxn][maxn]; //访问控制数组, 只要访问了, 就标记一下, 以免重复访问
int n, m, t, ok; //N M 是迷宫大小, T 是规定时间 OK 标记是否可以在规定时间到达
void dfs (int i, int j, int t1) { //DFS, i,j是起始位置, t1是时间
//printf("%c %d %d %d\n", a[i][j], i,j,t1);
if (t1 > t || ok == 1) //如果 时间超过规定时间 T 或者已经有路可以通过, 就直接返回就可以了
return;
if (t1 == t && a[i][j] == 'D') { //如果满足条件, 就把ok标记为1
ok = 1;
return;
}
if (a[i][j] == 'S' || a[i][j] == '.') {
vis[i][j] = 1; //这里要特别注意, 这里是为了避免这种情况 a -> b 然后访问b的时候 b -> a 又会访问a
if (i - 1 >= 0 && vis[i - 1][j] == 0) dfs (i - 1, j, t1 + 1); //向上走
if (j - 1 >= 0 && vis[i][j - 1] == 0) dfs (i, j - 1, t1 + 1); //向左走
if (j + 1 < m && vis[i][j + 1] == 0) dfs (i, j + 1, t1 + 1); //向右走
if (i + 1 < n && vis[i + 1][j] == 0) dfs (i + 1, j, t1 + 1); //向下走
vis[i][j] = 0; //把数组归零, 如果不归零,以前访问过后, 就不能再次访问这个点了
}
}
int main() {
// freopen ("in.txt", "r", stdin);
while (scanf ("%d %d %d", &n, &m, &t) == 3 && n + m + t) {
ok = 0 ;
int start_x, start_y;
for (int i = 0; i < n; i++) //数据读入
scanf("%s", &a[i]);
for (int i = 0 ; i < n; i++) {
for (int j = 0 ; j < m; j++) { //分析数据,找到开始点
vis[i][j] = 0;
if (a[i][j] == 'S') {
start_x = i;
start_y = j;
}
}
}
dfs (start_x, start_y, 0); //dfs
if (ok == 1) {
printf ("YES\n"); //输出结果
} else
printf ("NO\n");
}
}