2013-08-28 07:13:30Morris
[UVA][bfs] 985 - Round and Round Maze
Universidade da Beira Interior 21-10-2006
Problem G
Round and Round Maze
You have been blindfolded and brought to a strange complex of mazes. Each maze is divided in squares, each one with a strange circular plate with arrows on it. The start of each maze is on the upper left corner and the exit is always on the bottom right. The following figure shows an example maze:
![](http://uva.onlinejudge.org/external/9/p985a.png)
Figure 1: An example maze
![](http://uva.onlinejudge.org/external/9/p985b.png)
Figure 2: The quickest path to get out of the
example maze
Problem
Given a particular maze in the conditions described above, your task is to discover how much time does it take the quickest path from the upper left corner to the bottom right corner (the exit). You must also discover if that is not possible.Input
The input file contains several test cases, each of them as describes below. The input will start with a single line containing two numbers separated by a single space: R and C indicating respectively the number of rows and columns of the maze (2 R,C 500).Then there are exactly (R*C)-1 lines indicating in which directions are the arrows of each square pointing. These lines are given in a specific order, starting from the north to the south, and from the west to the east. This is, if we use the notation (row,column), the lines are given in the order (1,1),(1,2),...,(1,C),(2,1),...,(2,N),...,(R,1),...,(R,C-1). The bottom right corner (R,C) is not given, since it is always the exit.
Each of these lines contains a single string of length one to four chars, indicating the arrows of the plate on time 0. The chars belong to the set N,S,W,E and represent respectively an arrow pointing to North, South, West and East. See example input 1 for a representation of the example maze given in figure 1. There will not be repeated chars on the same line and the chars can appear in any order.
Output
For each test case, the output should contain a single line with an integer that represents the time taken by the quickest path from the start (always square (1,1)) to the exit (always (R,C)). Remember that the plates always rotate when you change your current square (therefore is does not help to stay on the same place waiting for a rotation - it won't happen!) and you can only follow the directions that the arrows point on the present time you are on that square.If there is no path from the start to the exit you should print "no path to exit".
Sample Input
2 2
NES
S
WS
3 2
NSWE
SW
SEW
NEW
SN
Sample Output
4
no path to exit
![](http://uva.onlinejudge.org/external/9/p985c.png)
Figure 3: The maze of the sample input 2
Maratona Inter-Universitária de Programação 2006 MIUP'2006
Author: Pedro Ribeiro (Universidade do Porto)#include <stdio.h>
題目描述:
每一格都有可轉移到其它相鄰的格子的限制,每走一步所有限制順時針轉 90 度,
求走到右下角 Exit 的最少時間。
題目解法:
很容易想,每一格最多 4 種狀態,也就是當前轉了 90, 180, 270, 360 度。
藉此進行 bfs 計算即可。
#include <string.h>
#include <queue>
#include <algorithm>
using namespace std;
int n, m;
int dx[] = {-1,0,1,0};//NESW
int dy[] = {0,1,0,-1};
int g[505][505][4];
int dist[505][505][4];
int trans(char c) {
switch(c) {
case 'N':return 0;
case 'E':return 1;
case 'S':return 2;
case 'W':return 3;
}
return -1;
}
void bfs() {
queue<int> X, Y, D;
int i, j, k;
int x, y, d;
int tx, ty;
for(i = 0; i < n; i++)
for(j = 0; j < m; j++)
dist[i][j][0] = dist[i][j][1] = dist[i][j][2] = dist[i][j][3] = 0;
X.push(0), Y.push(0), D.push(0);
while(!X.empty()) {
x = X.front(), X.pop();
y = Y.front(), Y.pop();
d = D.front(), D.pop();
for(i = 0; i < 4; i++) {
if(g[x][y][i] == 0) continue;
tx = x+dx[(i+d)%4], ty = y+dy[(i+d)%4];
if(tx < 0 || ty < 0 || tx >= n || ty >= m)
continue;
if(dist[tx][ty][(d+1)%4] == 0) {
dist[tx][ty][(d+1)%4] = dist[x][y][d]+1;
X.push(tx), Y.push(ty), D.push((d+1)%4);
}
}
}
int ret = 0xfffffff;
for(i = 0; i < 4; i++)
if(dist[n-1][m-1][i])
ret = min(ret, dist[n-1][m-1][i]);
if(ret == 0xfffffff)
puts("no path to exit");
else
printf("%d\n", ret);
}
int main() {
int i, j, k;
char s[10];
while(scanf("%d %d", &n, &m) == 2) {
while(getchar() != '\n');
memset(g, 0, sizeof(g));
for(i = 0; i < n; i++) {
for(j = 0; j < m; j++) {
if(i == n-1 && j == m-1)
continue;
gets(s);
for(k = 0; s[k]; k++)
g[i][j][trans(s[k])] = 1;
}
}
bfs();
}
return 0;
}