Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)
王被困在了一个3维的迷宫中,他很想逃离这个迷宫回去当学霸,你能帮助他么? 由于王很仁慈,他悄悄地告诉你,本题读入迷宫的每一行时,要用scanf("%s"...) ......
Input
多组测试数据,对于每组测试数据,有三个整数 L,R,C(0<l,r,c≤30)。
L代表迷宫的高度,R和C分别代表每一层的行和列。
接下来是L个R×C的矩阵,矩阵包含4种字符(S,E,.,#),S代表王的初始位置,E代表出口,#代表障碍。.代表能通过的地方。
每一层之后有一个空行。
当L=R=C=0时,输入中断。
Output
如果可以逃离迷宫,按下列格式输出最短时间:
Escaped in x minute(s). (x表示逃离迷宫的最短时间, 走一步花费一昏钟)
否则,输出:
Trapped!
Sample Input
3 4 5
S....
.###.
.##..
###.#
#####
#####
##.##
##...
#####
#####
#.###
####E
1 3 3
S##
#E#
###
0 0 0
Sample Output
Escaped in 11 minute(s).
Trapped!
原理不难,首先用三维数组map读入这个地图,读入过程中找到起点S,记录下它的位置并把它改为’#’,因为以后搜索时肯定就不会再往起点走了。
然后写BFS,首先写个队列,我是用结构数组来当队列的,存储位置和走到这里用的时间。然后先把起点入队,之后用尾指针tail把起点六个方向中能走到的地方入队,并且把能走到的地方在map上标记为’#’,因为是找最短时间,所以之后的路中就不会走已走过的路了。然后判断头指针的位置是不是出口’E’,不是的话就移动头指针,继续向下搜索。如此这样,直到找到出口。如果把能走的路都已走完的话,尾指针tail就不会再移动,然后头指针一直也移动到与尾指针相同时,便把所有能走到的地方遍历了一遍,如果没有找到出口,就返回0,表示Trapped!。
需要注意的就是输入输出用scanf(“%s”…)就行,因为每行之间是空白,scanf忽略空白。
另外对于每次地图,查询完之后,要清空数据,防止影响下组数据。
手写的队列,手写的BFS,一开始WA了半天,WA在了判断能否找到出口那,那个判断条件,一开始我写的head==tail,但是tail是下一次的入队的元素的下标。所以应该是head==tail-1。tail-1是当前队列的最后一个元素的坐标。
AC代码:
#include <iostream>
#include <cstdio>
#include <string>
#include <fstream>
#include <cstring>
using namespace std;
int l = 0, r = 0, c = 0, total = 0;//lrc为地图长宽高
int head = 0, tail = 1;//头尾指针
char map[32][32][32] = { '\0' };
int blank[3] = { 0 };//存储入口
struct queue
{
int fst;
int snd;
int trd;
int cnt;
}que[1000000];//队列
bool move(int set, int pos, int i, int j, int k)
{
if (i >= 0 && j >= 0 && k >= 0 && i<l && j<r && k< c && map[i][j][k] != '#')
{
que[pos].fst = i;//存储位置
que[pos].snd = j;
que[pos].trd = k;
que[pos].cnt = que[set].cnt + 1;//存储时间
if (map[i][j][k] != 'E')//记忆化,有人走过的地方就不再走了
map[i][j][k] = '#';
return true;
}
else return false;
}
int BFS(int i, int j, int k)
{
que[0].cnt = 0; que[0].fst = blank[0]; que[0].snd = blank[1]; que[0].trd = blank[2];
if (move(head, tail, i + 1, j, k))//往下搜索
tail++;
if (move(head, tail, i - 1, j, k))
tail++;
if (move(head, tail, i, j + 1, k))
tail++;
if (move(head, tail, i, j - 1, k))
tail++;
if (move(head, tail, i, j, k + 1))
tail++;
if (move(head, tail, i, j, k - 1))
tail++;
if (head == tail-1)//遍历之后没有找到
{
// printf("trap-head%d\n", head);
return 0;
}
else
{
head++;
if (map[que[head].fst][que[head].snd][que[head].trd] == 'E')//找到出口
{
// printf("tail%d\n", tail);
return que[head].cnt;
}
else
{
return BFS(que[head].fst, que[head].snd, que[head].trd);//继续搜索
}
}
}
int main()
{
int ans = 0;
memset(map, 0, sizeof(map));
memset(que, 0, sizeof(que));
while (scanf("%d %d %d", &l, &r, &c))//输入长宽高
{
if (l == 0 && r == 0 && c == 0) break;
total = l*r*c;
for (int i = 0; i < l; i++)//输入地图
{
for (int j = 0; j < r; j++)
{
scanf("%s", map[i][j]);
for (int k = 0; k < c; k++)
{
if (map[i][j][k] == 'S')
{
map[i][j][k] = '#';//存储入口
blank[0] = i; blank[1] = j; blank[2] = k;
}
}
}
}
ans = BFS(blank[0], blank[1], blank[2]);//搜索
if (ans > 0)//输出
{
printf("Escaped in %d minute(s).\n", ans);
}
else printf("Trapped!\n");
head = 0; tail = 1; ans = 0;//清空数据
memset(map, 0, sizeof(map));
memset(que, 0, sizeof(que));
}
return 0;
}