Hogwarts正式开学以后,Harry发现在Hogwarts里,某些楼梯并不是静止不动的,相反,他们每隔一分钟就变动一次方向.
比如下面的例子里,一开始楼梯在竖直方向,一分钟以后它移动到了水平方向,再过一分钟它又回到了竖直方向.Harry发现对他来说很难找到能使得他最快到达目的地的路线,这时Ron(Harry最好的朋友)告诉Harry正好有一个魔法道具可以帮助他寻找这样的路线,而那个魔法道具上的咒语,正是由你纂写的.
比如下面的例子里,一开始楼梯在竖直方向,一分钟以后它移动到了水平方向,再过一分钟它又回到了竖直方向.Harry发现对他来说很难找到能使得他最快到达目的地的路线,这时Ron(Harry最好的朋友)告诉Harry正好有一个魔法道具可以帮助他寻找这样的路线,而那个魔法道具上的咒语,正是由你纂写的.
Input
测试数据有多组,每组的表述如下:
第一行有两个数,M和N,接下来是一个M行N列的地图,'*'表示障碍物,'.'表示走廊,'|'或者'-'表示一个楼梯,并且标明了它在一开始时所处的位置:'|'表示的楼梯在最开始是竖直方向,'-'表示的楼梯在一开始是水平方向.地图中还有一个'S'是起点,'T'是目标,0<=M,N<=20,地图中不会出现两个相连的梯子.Harry每秒只能停留在'.'或'S'和'T'所标记的格子内.
第一行有两个数,M和N,接下来是一个M行N列的地图,'*'表示障碍物,'.'表示走廊,'|'或者'-'表示一个楼梯,并且标明了它在一开始时所处的位置:'|'表示的楼梯在最开始是竖直方向,'-'表示的楼梯在一开始是水平方向.地图中还有一个'S'是起点,'T'是目标,0<=M,N<=20,地图中不会出现两个相连的梯子.Harry每秒只能停留在'.'或'S'和'T'所标记的格子内.
Output
只有一行,包含一个数T,表示到达目标的最短时间.
注意:Harry只能每次走到相邻的格子而不能斜走,每移动一次恰好为一分钟,并且Harry登上楼梯并经过楼梯到达对面的整个过程只需要一分钟,Harry从来不在楼梯上停留.并且每次楼梯都恰好在Harry移动完毕以后才改变方向.
注意:Harry只能每次走到相邻的格子而不能斜走,每移动一次恰好为一分钟,并且Harry登上楼梯并经过楼梯到达对面的整个过程只需要一分钟,Harry从来不在楼梯上停留.并且每次楼梯都恰好在Harry移动完毕以后才改变方向.
Sample Input
5 5 **..T **.*. ..|.. .*.*. S....
Sample Output
7 附上代码: #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <iomanip> #include <queue> using namespace std; char map[22][22]; int visit[22][22]; int dr[4]={1,-1,0,0}; int dc[4]={0,0,1,-1}; struct node{ int x,y,step; }; int n,m,si,sj,endx,endy; int bfs() { int xx,yy; queue<node> Q; node a,b; a.x=si,a.y=sj,a.step=0; Q.push(a); while(!Q.empty()) { a=Q.front(); Q.pop(); if(a.x==endx && a.y==endy) { return a.step; } for(int i=0;i<4;i++) { xx=a.x+dr[i]; yy=a.y+dc[i]; if(xx>=1 && yy>=1 && xx<=m && yy<=n && map[xx][yy]!='*' && visit[xx][yy]==0) { if(map[xx][yy]=='.' || map[xx][yy]=='T') { b.x=xx,b.y=yy,b.step=a.step+1; Q.push(b); visit[b.x][b.y]=1; }else if(map[xx][yy]=='-')//开始楼梯横向 { if(a.step%2==0)//偶数时方向不发生变化 { if(xx==a.x)//判断是否是横向进来的 { if(yy==a.y+1)//向右走 { yy=yy+1; }else{ yy=yy-1; } if(yy>=1 && yy<=n && map[xx][yy]!='*' && visit[xx][yy]==0) { b.x=xx,b.y=yy,b.step=a.step+1; Q.push(b); visit[b.x][b.y]=1; } }else{//停留等楼梯的情况 b.x=a.x,b.y=a.y,b.step=a.step+1; Q.push(b); } }else{//奇数时间,楼梯变了方向了 if(yy==a.y)//此刻楼梯变成竖直方向了 { if(xx==a.x+1)//向下走 { xx=xx+1; }else{ xx=xx-1; } if(xx>=1 && xx<=m && map[xx][yy]!='*' && visit[xx][yy]==0) { b.x=xx,b.y=yy,b.step=a.step+1; Q.push(b); visit[b.x][b.y]=1; } }else{//停留 b.x=a.x,b.y=a.y,b.step=a.step+1; Q.push(b); } } }else if(map[xx][yy]=='|') { if(a.step%2==0) { if(yy==a.y)//判断是否是竖向进来的 { if(xx==a.x+1)//向下走 { xx=xx+1; }else{ xx=xx-1; } if(xx>=1 && xx<=m && map[xx][yy]!='*' && visit[xx][yy]==0) { b.x=xx,b.y=yy,b.step=a.step+1; Q.push(b); visit[b.x][b.y]=1; } }else{//停留等楼梯的情况 b.x=a.x,b.y=a.y,b.step=a.step+1; Q.push(b); } }else{//奇数时间,楼梯变了方向了 if(xx==a.x)//此刻变成了横向进入 { if(yy==a.y+1)//向右走 { yy=yy+1; }else{ yy=yy-1; } if(yy>=1 && yy<=n && map[xx][yy]!='*' && visit[xx][yy]==0) { b.x=xx,b.y=yy,b.step=a.step+1; Q.push(b); visit[b.x][b.y]=1; } }else{//停留 b.x=a.x,b.y=a.y,b.step=a.step+1; Q.push(b); } } } } } } return -1; } int main(){ int i,j; while(cin>>m>>n) { for(i=1;i<=m;i++) { for(j=1;j<=n;j++) { cin>>map[i][j]; if(map[i][j]=='S')//从终点往起点搜,时间好像少点 { si=i; sj=j; }else if(map[i][j]=='T') { endx=i; endy=j; } } } memset(visit,0,sizeof(visit)); visit[si][sj]=1; int ans=bfs(); cout<<ans<<endl; } return 0; }