题意:如上图,就是以左上方的点看作坐标原点,构造坐标系,按正常看的x轴正方向,z轴负方向,y轴正方向依次填入,0为路,1为墙,右下角为出口。
算法:BFS
问题:一开始因为之前习惯把t当成组数,但本题中t还代表魔王回来的时间,搞混了,wa了两发才发现。
思路:把基本的二维的BFS扩展成三维即可,可以先特判一下出口不能走的情况,减少运算。
代码:ac
#include<bits/stdc++.h>
using namespace std;
int Map[60][60][60];
int vis[60][60][60];
int a, b, c, t;
int dir[6][3] = { {0,0,1},{0,0,-1}, {0,1,0}, {0,-1,0}, {1,0,0}, {-1,0,0} };
struct pos {
int x, y, z;
int time;
};
int q;
void bfs();
int main()
{
scanf("%d", &q);
for (int p = 1; p <= q; p++) {
scanf("%d%d%d%d", &a, &b, &c, &t);
for(int i=1;i<=a;i++)
for(int j=1;j<=b;j++)
for (int k = 1; k <= c; k++) {
scanf("%d", &Map[i][j][k]);
vis[i][j][k] = 0;
}
bfs();
}
return 0;
}
void bfs()
{
if (Map[a][b][c] == 1) {/*特判出口不能走的情况*/
printf("-1\n");
return;
}
queue<pos>qu;
pos cur, nex;
cur.time = 0;
cur.x = 1, cur.y = 1, cur.z = 1;
qu.push(cur);
vis[1][1][1] = 1;
while (!qu.empty()) {
cur = qu.front();
qu.pop();
if (cur.x == a && cur.y == b && cur.z == c) {/*到达*/
printf("%d\n", cur.time);
return;
}
if (cur.time >= t) {/*超时,如果恰好到前一个if已经return了,所以这里取到等号*/
printf("-1\n");
return;
}
for (int i = 0; i < 6; i++) {
nex.time = cur.time + 1;
nex.x = cur.x + dir[i][0];
nex.y = cur.y + dir[i][1];
nex.z = cur.z + dir[i][2];
if (Map[nex.x][nex.y][nex.z] == 1)continue;
if (nex.x<1 || nex.x>a || nex.y<1 || nex.y>b || nex.z<1 || nex.z>c)continue;
if (vis[nex.x][nex.y][nex.z])continue;
vis[nex.x][nex.y][nex.z] = 1;
qu.push(nex);
}
}
printf("-1\n");
}