题目:
ProblemDescription
Hogwarts正式开学以后,Harry发现在Hogwarts里,某些楼梯并不是静止不动的,相反,他们每隔一分钟就变动一次方向.
比如下面的例子里,一开始楼梯在竖直方向,一分钟以后它移动到了水平方向,再过一分钟它又回到了竖直方向.Harry发现对他来说很难找到能使得他最快到达目的地的路线,这时Ron(Harry最好的朋友)告诉Harry正好有一个魔法道具可以帮助他寻找这样的路线,而那个魔法道具上的咒语,正是由你纂写的.
Input
测试数据有多组,每组的表述如下:
第一行有两个数,M和N,接下来是一个M行N列的地图,'*'表示障碍物,'.'表示走廊,'|'或者'-'表示一个楼梯,并且标明了它在一开始时所处的位置:'|'表示的楼梯在最开始是竖直方向,'-'表示的楼梯在一开始是水平方向.地图中还有一个'S'是起点,'T'是目标,0<=M,N<=20,地图中不会出现两个相连的梯子.Harry每秒只能停留在'.'或'S'和'T'所标记的格子内.
Output
只有一行,包含一个数T,表示到达目标的最短时间.
注意:Harry只能每次走到相邻的格子而不能斜走,每移动一次恰好为一分钟,并且Harry登上楼梯并经过楼梯到达对面的整个过程只需要一分钟,Harry从来不在楼梯上停留.并且每次楼梯都恰好在Harry移动完毕以后才改变方向.
Sample Input
5 5
**..T
**.*.
..|..
.*.*.
S....
Sample Output
7
Hint
Hint
地图如下:
分析:BFS。。。。判断走了奇数步还是偶数步,判断是否可以通行,一开始没注意到可以停留,,,代码有点繁琐。。。。。。
代码:
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
int m, n;
char ch[22][22];
int num[22][22];
typedef pair<int, int>P;
int next1[4][2] = { { 0,1 },{ 1,0 },{ 0,-1 },{ -1,0 } };
int bfs(int ax, int ay, int ex, int ey)
{
queue<P>q; int nx, ny;
while (!q.empty())
q.pop();
q.push(P(ax, ay));
num[ax][ay] = 1;
while (!q.empty())
{
P fx = q.front();
if (fx.first == ex&&fx.second == ey)
return num[ex][ey];
for (int i = 0; i <=3; i++)
{
nx = fx.first + next1[i][0];
ny = fx.second + next1[i][1];
if (nx >= 0 && nx < m&&ny >= 0 && ny < n)
{
if (ch[nx][ny] == 'T')
{
q.push(P(nx, ny));
num[nx][ny] = num[fx.first][fx.second] + 1;
}
if (ch[nx][ny] == '.')
{
if (!num[nx][ny])
{
num[nx][ny] = num[fx.first][fx.second] + 1;
q.push(P(nx, ny));
}
}
if (ch[nx][ny] == '|')
{
if (num[fx.first][fx.second] % 2 != 0)
{
if (i == 1 && nx + 1 < m&& (ch[nx + 1][ny] == '.' || ch[nx + 1][ny] == 'T'))
{
if (num[nx + 1][ny])
{
if (num[nx + 1][ny] > num[fx.first][fx.second] + 1)
num[nx + 1][ny] = num[fx.first][fx.second] + 1;
}
else
{
num[nx + 1][ny] = num[fx.first][fx.second] + 1;
num[nx][ny] = 1;
q.push(P(nx + 1, ny));
}
}
if (i == 3 && nx - 1 >= 0 && (ch[nx -1][ny] == '.'|| ch[nx - 1][ny] == 'T'))
{
if (num[nx - 1][ny])
{
if (num[nx - 1][ny] > num[fx.first][fx.second] + 1)
num[nx - 1][ny] = num[fx.first][fx.second] + 1;
}
else
{
num[nx - 1][ny] = num[fx.first][fx.second] + 1;
num[nx][ny] = 1;
q.push(P(nx - 1, ny));
}
}
if (i == 2 && ny - 1 >= 0 && (ch[nx][ny - 1] == '.' || ch[nx][ny - 1] == 'T') )
{
if (num[nx][ny - 1])
{
if (num[nx][ny - 1] > num[fx.first][fx.second] +2)
num[nx][ny - 1] = num[fx.first][fx.second] + 2;
}
else
{
num[nx][ny - 1] = num[fx.first][fx.second] + 2;
num[nx][ny] = 1;
q.push(P(nx, ny - 1));
}
}
if (i == 0 && ny + 1 < n && (ch[nx][ny+1] == '.' || ch[nx][ny+1] == 'T') )
{
if (num[nx][ny + 1])
{
if (num[nx][ny + 1] > num[fx.first][fx.second] + 2)
num[nx][ny + 1] = num[fx.first][fx.second] + 2;
}
else
{
num[nx][ny + 1] = num[fx.first][fx.second] + 2;
num[nx][ny] = 1;
q.push(P(nx, ny + 1));
}
}
}
if (num[fx.first][fx.second] % 2 == 0)
{
if (i == 2 && ny - 1 >= 0&&(ch[nx][ny-1]=='.'|| ch[nx][ny - 1] == 'T'))
{
if (num[nx][ny - 1])
{
if (num[nx][ny - 1] > num[fx.first][fx.second] + 1)
num[nx][ny - 1] = num[fx.first][fx.second] + 1;
}
else
{
num[nx][ny - 1] = num[fx.first][fx.second] + 1;
num[nx][ny] = 1;
q.push(P(nx, ny - 1));
}
}
if (i == 0 && ny + 1 < n && (ch[nx][ny + 1] == '.' || ch[nx][ny + 1] == 'T') )
{
if (num[nx][ny + 1])
{
if (num[nx][ny + 1] > num[fx.first][fx.second] + 1)
num[nx][ny + 1] = num[fx.first][fx.second] + 1;
}
else
{
num[nx][ny + 1] = num[fx.first][fx.second] + 1;
num[nx][ny] = 1;
q.push(P(nx, ny + 1));
}
}
if (i == 1 && nx + 1 < m&&(ch[nx + 1][ny] == '.'|| ch[nx + 1][ny] == 'T') )
{
if (num[nx + 1][ny])
{
if (num[nx + 1][ny] > num[fx.first][fx.second] + 2)
num[nx + 1][ny] = num[fx.first][fx.second] + 2;
}
else
{
num[nx + 1][ny] = num[fx.first][fx.second] + 2;
num[nx][ny] = 1;
q.push(P(nx + 1, ny));
}
}
if (i == 3 && nx - 1 >= 0 && (ch[nx - 1][ny] == '.' || ch[nx - 1][ny] == 'T') )
{
if (num[nx - 1][ny])
{
if (num[nx - 1][ny] > num[fx.first][fx.second] + 2)
num[nx - 1][ny] = num[fx.first][fx.second] + 2;
}
else
{
num[nx - 1][ny] = num[fx.first][fx.second] + 2;
num[nx][ny] = 1;
q.push(P(nx - 1, ny));
}
}
}
}
if (ch[nx][ny] == '-')
{
if (num[fx.first][fx.second] % 2 == 0)
{
if (i == 1 && nx + 1 < m&& (ch[nx + 1][ny] == '.' || ch[nx + 1][ny] == 'T') )
{
if (num[nx + 1][ny])
{
if (num[nx + 1][ny] > num[fx.first][fx.second] + 1)
num[nx + 1][ny] = num[fx.first][fx.second] + 1;
}
else
{
num[nx + 1][ny] = num[fx.first][fx.second] + 1;
num[nx][ny] = 1;
q.push(P(nx + 1, ny));
}
}
if (i == 3 && nx - 1 >= 0 && (ch[nx - 1][ny] == '.' || ch[nx - 1][ny] == 'T'))
{
if (num[nx - 1][ny])
{
if (num[nx - 1][ny] > num[fx.first][fx.second] + 1)
num[nx - 1][ny] = num[fx.first][fx.second] + 1;
}
else
{
num[nx - 1][ny] = num[fx.first][fx.second] + 1;
num[nx][ny] = 1;
q.push(P(nx - 1, ny));
}
}
if (i == 2 && ny - 1 >= 0 && (ch[nx][ny - 1] == '.' || ch[nx][ny - 1] == 'T') )
{
if (num[nx][ny - 1])
{
if (num[nx][ny - 1] > num[fx.first][fx.second] + 2)
num[nx][ny - 1] = num[fx.first][fx.second] + 2;
}
else
{
num[nx ][ny-1] = num[fx.first][fx.second] + 2;
num[nx][ny] = 1;
q.push(P(nx, ny-1));
}
}
if (i == 0 && ny + 1 < n&& (ch[nx][ny + 1] == '.' || ch[nx][ny + 1] == 'T'))
{
if (num[nx][ny + 1])
{
if (num[nx][ny + 1] > num[fx.first][fx.second] + 2)
num[nx][ny + 1] = num[fx.first][fx.second] + 2;
}
else
{
num[nx][ny + 1] = num[fx.first][fx.second] + 2;
num[nx][ny] = 1;
q.push(P(nx, ny + 1));
}
}
}
if (num[fx.first][fx.second] % 2 != 0)
{
if (i == 2 && ny - 1 >= 0 && (ch[nx][ny - 1] == '.'|| ch[nx][ny - 1] == 'T') )
{
if (num[nx][ny - 1])
{
if (num[nx][ny - 1] > num[fx.first][fx.second] + 1)
num[nx][ny - 1] = num[fx.first][fx.second] + 1;
}
else
{
num[nx][ny - 1] = num[fx.first][fx.second] + 1;
num[nx][ny] = 1;
q.push(P(nx, ny - 1));
}
}
if (i == 0 && ny + 1 < n&&(ch[nx][ny + 1] == '.'|| ch[nx][ny + 1] == 'T'))
{
if (num[nx][ny + 1])
{
if (num[nx][ny + 1] > num[fx.first][fx.second] + 1)
num[nx][ny + 1] = num[fx.first][fx.second] + 1;
}
else
{
num[nx][ny + 1] = num[fx.first][fx.second] + 1;
num[nx][ny] = 1;
q.push(P(nx, ny + 1));
}
}
if (i == 1 && nx + 1 < m && (ch[nx + 1][ny] == '.' || ch[nx + 1][ny] == 'T') )
{
if (num[nx + 1][ny])
{
if (num[nx + 1][ny] > num[fx.first][fx.second] + 2)
num[nx + 1][ny] = num[fx.first][fx.second] + 2;
}
else
{
num[nx + 1][ny] = num[fx.first][fx.second] + 2;
num[nx][ny] = 1;
q.push(P(nx + 1, ny));
}
}
if (i == 3 && nx - 1 >= 0 && (ch[nx - 1][ny] == '.' || ch[nx - 1][ny] == 'T') )
{
if (num[nx - 1][ny])
{
if (num[nx - 1][ny] > num[fx.first][fx.second] + 2)
num[nx - 1][ny] = num[fx.first][fx.second] + 2;
}
else
{
num[nx - 1][ny] = num[fx.first][fx.second] + 2;
num[nx][ny] = 1;
q.push(P(nx - 1, ny));
}
}
}
}
}
}
q.pop();
}
}
int main()
{
int a, b, c, d;
while (scanf("%d%d", &m, &n) != EOF)
{
memset(num, 0, sizeof(num));
for (int i = 0; i < m; i++)
scanf("%s", ch[i]);
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
{
if (ch[i][j] == 'S')
{
a = i; b = j;
}
if (ch[i][j] == 'T')
{
c = i; d = j;
}
}
printf("%d\n", bfs(a, b, c, d) - 1);
}
return 0;
}