题干:
小z身处在一个迷宫中,小z每分钟可以走到上下左右四个方向的相邻格之一。迷宫中有一些墙和障碍物。
同时迷宫中也有一些传送门,当小z走到任意一个传送门时,可以选择传送到其他任意的传送门(传送是不花费时间的),
当然也可以停留在原地。现在小z想知道走出迷宫需要花费的最少时间。
Input
输入第一行为组数T(t<=10)。
对于每组数据第一行为两个整数R和C(1<=R,C<=100)。以下R行每行有C个字符,即迷宫地图。
其中"#"代表墙和障碍物,"."表示空地,"P"表示传送门,"Z"表示小z的起始位置,"W"表示迷宫出口。
对于每组数据保证起始位置和迷宫出口唯一。
Output
对于每组数据,输出走出迷宫的最短时间(单位:分钟)。如果无法走出迷宫则输出"IMPOSSIBLE"。
Sample Input
2
3 4
.Z..
.P#.
##PW
4 4
Z..P
....
##..
W#.P
Sample Output
2
IMPOSSIBLE
解题报告:
裸。bfs复习。
AC代码:
using namespace std;
const int MAX = 2e3 + 5;
struct N {
int x,y;
N(){}
N(int x,int y):x(x),y(y){}
} p[MAX];
struct Node {
int x,y;
int t;
Node(){}
Node(int x,int y,int t):x(x),y(y),t(t){}
};
bool vis[505][505];
int tot,r,c;
char maze[505][505];
int nx[4] = {0,1,0,-1};
int ny[4] = {1,0,-1,0};
int bfs(N st,N ed) {
queue<Node> q;
q.push(Node(st.x,st.y,0));
while(q.size()) {
Node cur = q.front();q.pop();
if(cur.x == ed.x && cur.y == ed.y) return cur.t;
if(vis[cur.x][cur.y]) continue;
vis[cur.x][cur.y] = 1;
for(int k = 0; k<4; k++) {
int tx = cur.x + nx[k];
int ty = cur.y + ny[k];
if(tx < 1 || tx > r || ty < 1 || ty > c) continue;
if(maze[tx][ty] == '#') continue;
q.push(Node(tx,ty,cur.t+1));
}
if(maze[cur.x][cur.y] == 'P') {
for(int l = 1; l<=tot; l++) {
if(p[l].x == cur.x && p[l].y == cur.y) continue;
q.push(Node(p[l].x,p[l].y,cur.t));
}
}
}
return -1;
}
int main()
{
int t;
cin>>t;
while(t--) {
tot=0;
memset(vis,0,sizeof vis);
scanf("%d%d",&r,&c);
for(int i = 1; i<=r; i++) {
scanf("%s",maze[i] + 1);
}
int stx,sty,edx,edy;
for(int i = 1; i<=r; i++) {
for(int j = 1; j<=c; j++) {
if(maze[i][j] == 'Z') stx = i,sty = j;
if(maze[i][j] == 'W') edx = i,edy = j;
if(maze[i][j] == 'P') p[++tot] = N(i,j);
}
}
int ans = bfs(N(stx,sty),N(edx,edy));
if(ans == -1) printf("IMPOSSIBLE\n");
else printf("%d\n",ans);
}
return 0 ;
}
/*
14:46 - 14:57
*/