题目描述: Ignatius被魔王抓走了,有一天魔王出差去了,这可是Ignatius逃亡的好机会.
|
Input 输入数据的第一行是一个正整数K,表明测试数据的数量.每组测试数据的第一行是四个正整数A,B,C和T(1<=A,B,C<=50,1<=T<=1000),它们分别代表城堡的大小和魔王回来的时间.然后是A块输入数据(先是第0块,然后是第1块,第2块......),每块输入数据有B行,每行有C个正整数,代表迷宫的布局,其中0代表路,1代表墙.(如果对输入描述不清楚,可以参考Sample Input中的迷宫描述,它表示的就是上图中的迷宫)
Output 对于每组测试数据,如果Ignatius能够在魔王回来前离开城堡,那么请输出他最少需要多少分钟,否则输出-1.
Sample Input
Sample Output 11 |
主人公每次行走仅能走到上、下、左、右、前、后与主人公所在点相邻的位置、
即从(x,y,z)点行走至(x-1,y,z)、(x+1,y,z)、(x,y+1,z)、(x,y-1,z)、(x,y,z+1)、(x,y,z-1)六个点的其中一个。在这其中还存在着一些墙。
由于可以由任意一个点经过一秒的行走进入下一个点,所以由任意一个状态(x,y,z,t)可以扩展得到下面六个状态
(x-1,y,z,t+1)、(x+1,y,z,t+1)、
(x,y+1,z,t+1)、(x,y-1,z,t+1)、
(x,y,z+1,t+1)、(x,y,z-1,t+1)
先由根结点扩展出所有深度为 1 的结点,再由每一个深度为 1 的结点扩展出所有深度为 2 的结点,依次类推。
即便这样所需查找的状态还是非常得多,最坏情况下,因为每个结点都能扩展出六个新结点,那么仅走了 10 步,其状态数就会达到 6 的十次方,需要大量的时间才能依次遍历完这些状态。那么,我们必须采取相应的措施来制约状态的无限扩展。这个措施被称为剪枝。
若有状态(x,y,z,t),其中 t 不是从起点到达(x,y,z)的最短时间,那么我们所要查找的答案必不可能由该状态进行
若干次扩展后得到。
为了防止对无效状态的搜索,我们需要一个标记数组 mark[x][y][z],当已经得到过包含坐标(x,y,z)的状态后,即把 mark[x][y][z]置为 true,当下次再由某状态扩展出包含该坐标的状态时,则直接丢弃,不对其进行任何处理。
平面的走动:
原点:0,0
向下:1,0
向上:-1,0
向右:0,1
向左:0,-1
三维的走动:
原点:
0,0,0
向下:0,1,0
向上:0,-1,0
向右:0,0,1
向左:0,0,-1
从第0层走向第一层
升高:1,0,0
降低:-1,0,0
#include <iostream>
#include <queue>
#include <cstdio>
using namespace std;
int maze[51][51][51];// 储存迷宫 0代表路,1代表墙
bool mark[51][51][51]; // 1代表已经去过 0代表没去过
int a, b, c, t; //输入数据(先是第0块,然后是第1块,第2块......第a块),每块输入数据有B行,每行有C个正整数
typedef struct Now {
int x, y, z;
int t;
} Now;
queue<Now> q;
void printNow(Now& a) {
cout << "pos: zyx:" << a.z << " " << a.y << " " << a.x << " t :" << a.t << endl;
}
void markNow(Now& a) {
cout << "mark: zyx:" << a.z << " " << a.y << " " << a.x << " t :" << a.t << endl;
}
int bfs(int z, int y, int x) {
//从第z层,第y行 第x个元素开始 走到 c b a
//清空queue
while(!q.empty()) {
q.pop();
}
Now start;
start.z = z;
start.y = y;
start.x = x;
start.t = 0;
Now father;
Now child;
q.push(start);
while(!q.empty()) {
father = q.front();
q.pop();// 父亲出来,接下来的6个孩子进去
// printNow(father);
if (father.z == a && father.y == b && father.x == c) {
return father.t;
}
// WASD // 穿层
//上
if (father.y - 1 >= 1 && maze[father.z][father.y - 1][father.x] == 0 && mark[father.z][father.y - 1][father.x] == 0 ) {
child = father;
child.y --;
child.t ++;
mark[child.z][child.y][child.x] = 1;
//markNow(child);
q.push(child);
}
//下
if (father.y + 1 <= b && maze[father.z][father.y + 1][father.x] == 0 && mark[father.z][father.y + 1][father.x] == 0 ) {
child = father;
child.y ++;
child.t ++;
mark[child.z][child.y][child.x] = 1;
//markNow(child);
q.push(child);
}
//左
if (father.x - 1 >= 1 && maze[father.z][father.y][father.x - 1] == 0 && mark[father.z][father.y][father.x - 1] == 0 ) {
child = father;
child.x --;
child.t ++;
mark[child.z][child.y][child.x] = 1;
//markNow(child);
q.push(child);
}
// 右
if (father.x + 1 <= c && maze[father.z][father.y][father.x + 1] == 0 && mark[father.z][father.y][father.x + 1] == 0 ) {
child = father;
child.x ++;
child.t ++;
mark[child.z][child.y][child.x] = 1;
// markNow(child);
q.push(child);
}
//前
if (father.z - 1 >= 1 && maze[father.z - 1][father.y][father.x] == 0 && mark[father.z - 1][father.y][father.x] == 0 ) {
child = father;
child.z --;
child.t ++;
mark[child.z][child.y][child.x] = 1;
//markNow(child);
q.push(child);
}
//后
if (father.z + 1 <= a && maze[father.z + 1][father.y][father.x] == 0 && mark[father.z + 1][father.y][father.x] == 0 ) {
child = father;
child.z ++;
child.t ++;
mark[child.z][child.y][child.x] = 1;
//markNow(child);
q.push(child);
}
}
return -1;
}
//打印出来
void show() {
for (int i = 1; i <= a; i ++) {
for (int j = 1; j <= b; j++) {
for (int k = 1; k <= c; k++) {
cout << maze[i][j][k] << " ";
}
cout << endl;
}
cout << endl;
}
cout << endl;
}
int main() {
int caseNum;
cin >> caseNum;
for (int caseNo = 1; caseNo <= caseNum; caseNo ++) {
cin >> a >> b >> c >> t; // a层 b行 每行c个元素 // 3 3 4
for (int i = 1; i <= a; i++) {
for (int j = 1; j <= b; j++) {
for (int k = 1; k <= c; k++) {
scanf("%d",&maze[i][j][k]) ;
mark[i][j][k] = 0;
}
}
}
//show();
// 从1 1 1到 a b c
int res = bfs(1, 1, 1);
if (res != -1 && res<= t) {
cout << res << endl;
} else {
cout << -1 << endl;
}
}
}
#include <iostream>
#include <queue>
using namespace std;
bool maze[51][51][51];
bool mark[51][51][51];
int a,b,c;// a块数据 // 每块为 b * c // b行 C列
int time;
typedef struct Now {
int z,y,x;
int t;
} Now;
queue<Now> q;
int bfs() {
while(!q.empty()) {
q.pop();
}
Now chu;
chu.z = chu.y = chu.x = 1;
chu.t = 0;
mark[1][1][1] = 1;
Now father;
Now child;
q.push(chu);
while(!q.empty()) {
father = q.front();
q.pop();
// 父亲出来 孩子进去
// 上 y--
if (father.y - 1 >= 1 && maze[father.z][father.y-1][father.x] == 0 && mark[father.z][father.y-1][father.x] == 0) {
child = father;
child.y--;
child.t++;
if (child.t > time) {
// 大于时间,就不加入了
} else if (child.z == a && child.y == b && child.x == c && child.t <= time) {
return child.t;// 到出口了
} else {
mark[child.z][child.y][child.x] = 1;
q.push(child);
}
}
// 下 y++
if (father.y + 1 <= b && maze[father.z][father.y+1][father.x] == 0 && mark[father.z][father.y+1][father.x] == 0) {
child = father;
child.y++;
child.t++;
if (child.t > time) {
// 大于时间,就不加入了
} else if (child.z == a && child.y == b && child.x == c && child.t <= time) {
return child.t;// 到出口了
} else {
mark[child.z][child.y][child.x] = 1;
q.push(child);
}
}
// 左 x--
if (father.x - 1 >= 1 && maze[father.z][father.y][father.x-1] == 0 && mark[father.z][father.y][father.x-1] == 0) {
child = father;
child.x--;
child.t++;
if (child.t > time) {
// 大于时间,就不加入了
} else if (child.z == a && child.y == b && child.x == c && child.t <= time) {
return child.t;// 到出口了
} else {
mark[child.z][child.y][child.x] = 1;
q.push(child);
}
}
// 右 x++
if (father.x + 1 <= c && maze[father.z][father.y][father.x+1] == 0 && mark[father.z][father.y][father.x+1] == 0) {
child = father;
child.x++;
child.t++;
if (child.t > time) {
// 大于时间,就不加入了
} else if (child.z == a && child.y == b && child.x == c && child.t <= time) {
return child.t;// 到出口了
} else {
mark[child.z][child.y][child.x] = 1;
q.push(child);
}
}
// 升 z++
if (father.z + 1 <= a && maze[father.z+1][father.y][father.x] == 0 && mark[father.z+1][father.y][father.x] == 0) {
child = father;
child.z++;
child.t++;
if (child.t > time) {
// 大于时间,就不加入了
} else if (child.z == a && child.y == b && child.x == c && child.t <= time) {
return child.t;// 到出口了
} else {
mark[child.z][child.y][child.x] = 1;
q.push(child);
}
}
// 降 z--
if (father.z - 1 >= 1 && maze[father.z-1][father.y][father.x] == 0 && mark[father.z-1][father.y][father.x] == 0) {
child = father;
child.z--;
child.t++;
if (child.t > time) {
// 大于时间,就不加入了
} else if (child.z == a && child.y == b && child.x == c && child.t <= time) {
return child.t;// 到出口了
} else {
mark[child.z][child.y][child.x] = 1;
q.push(child);
}
}
}
return -1;
}
int main() {
int caseNum;
cin >> caseNum;
for (int caseNo = 1; caseNo <= caseNum; caseNo ++) {
cin >> a >> b >> c >> time;
for (int i = 1; i <= a; i ++) {
for (int j = 1; j <= b; j++) {
for (int k = 1; k <= c; k++) {
scanf("%d",&maze[i][j][k]);
mark[i][j][k] = 0;
}
}
}
int res = bfs();
cout << res << endl;
}
}