D
来源:互联网 发布:可可网络验证破解 编辑:程序博客网 时间:2024/05/10 03:45
Hogwarts正式开学以后,Harry发现在Hogwarts里,某些楼梯并不是静止不动的,相反,他们每隔一分钟就变动一次方向.
比如下面的例子里,一开始楼梯在竖直方向,一分钟以后它移动到了水平方向,再过一分钟它又回到了竖直方向.Harry发现对他来说很难找到能使得他最快到达目的地的路线,这时Ron(Harry最好的朋友)告诉Harry正好有一个魔法道具可以帮助他寻找这样的路线,而那个魔法道具上的咒语,正是由你纂写的.
比如下面的例子里,一开始楼梯在竖直方向,一分钟以后它移动到了水平方向,再过一分钟它又回到了竖直方向.Harry发现对他来说很难找到能使得他最快到达目的地的路线,这时Ron(Harry最好的朋友)告诉Harry正好有一个魔法道具可以帮助他寻找这样的路线,而那个魔法道具上的咒语,正是由你纂写的.
第一行有两个数,M和N,接下来是一个M行N列的地图,'*'表示障碍物,'.'表示走廊,'|'或者'-'表示一个楼梯,并且标明了它在一开始时所处的位置:'|'表示的楼梯在最开始是竖直方向,'-'表示的楼梯在一开始是水平方向.地图中还有一个'S'是起点,'T'是目标,0<=M,N<=20,地图中不会出现两个相连的梯子.Harry每秒只能停留在'.'或'S'和'T'所标记的格子内.
注意:Harry只能每次走到相邻的格子而不能斜走,每移动一次恰好为一分钟,并且Harry登上楼梯并经过楼梯到达对面的整个过程只需要一分钟,Harry从来不在楼梯上停留.并且每次楼梯都恰好在Harry移动完毕以后才改变方向.
5 5**..T**.*...|...*.*.S....
7 地图如下:
#include<stdio.h> #include<string.h> #include<queue> using namespace std; char s[22][22]; int vis[22][22]; int to[][2]= {0,1,0,-1,1,0,-1,0}; int n,m; struct node { int x,y,step; }; int judge(int x,int y)//判断是否符合条件 { if(x>=0&&x<n&&y>=0&&y<m&&!vis[x][y]&&s[x][y]!='*') return 1; return 0; } int bfs(int x,int y) { memset(vis,0,sizeof(vis)); node now,next; queue<node>q; now.x=x,now.y=y,now.step=0; vis[x][y]=1; q.push(now); while(!q.empty()) { now=q.front(); if(s[now.x][now.y]=='T') return now.step; int flag=0,flog=0;//flag记录本次原地待命的次数,flog用来判断如果楼梯能走,那么过楼梯后的点是否已走过 for(int i=0; i<4; i++) { int xx=now.x+to[i][0],yy=now.y+to[i][1]; if(judge(xx,yy)) { next.step=now.step+1; if(s[xx][yy]=='|') { if(s[xx+to[i][0]][yy+to[i][1]]=='*')//判断楼梯后面是否是墙 continue; if(next.step&1)//下一步之后还是'|' { if(to[i][0]!=0)//如果是上下走 xx+=to[i][0],flog=1; else//否则,则原地待步 xx-=to[i][0],yy-=to[i][1],flag++; } else//'|'变成了'-' { if(to[i][0]==0)//如果是左右走 yy+=to[i][1],flog=1; else//否则,则原地待步 xx-=to[i][0],yy-=to[i][1],flag++; } } else if(s[xx][yy]=='-')//同上 { if(s[xx+to[i][0]][yy+to[i][1]]=='*') continue; if(next.step&1)//下一步之后还是'-' { if(to[i][0]==0)//如果左右走 yy+=to[i][1],flog=1; else //上下走 原地待步 xx-=to[i][0],yy-=to[i][1],flag++; } else { if(to[i][0]!=0) xx+=to[i][0],flog=1; else xx-=to[i][0],yy-=to[i][1],flag++; } } if(flag>1||(flog&&vis[xx][yy]))//如果本次已经有过原地待命或者(楼梯能走,但是楼梯后的点是已走过的点)(剪枝,不减会爆内存) continue; vis[xx][yy]=1; next.x=xx,next.y=yy; q.push(next); } } q.pop(); } } int main() { while(~scanf("%d%d",&n,&m)) { int i,j,x,y; for(i=0; i<n; i++) { scanf("%s",s[i]); for(j=0; j<m; j++) { if(s[i][j]=='S') x=i,y=j; } } int ans=bfs(x,y); printf("%d\n",ans); } return 0; }
阅读全文
0 0