hdu 1180 诡异的楼梯(BFS)
2014-08-06 23:12
295 查看
诡异的楼梯
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 8913 Accepted Submission(s): 2205
[align=left]Problem Description[/align]
Hogwarts正式开学以后,Harry发现在Hogwarts里,某些楼梯并不是静止不动的,相反,他们每隔一分钟就变动一次方向.
比如下面的例子里,一开始楼梯在竖直方向,一分钟以后它移动到了水平方向,再过一分钟它又回到了竖直方向.Harry发现对他来说很难找到能使得他最快到达目的地的路线,这时Ron(Harry最好的朋友)告诉Harry正好有一个魔法道具可以帮助他寻找这样的路线,而那个魔法道具上的咒语,正是由你纂写的.
[align=left]Input[/align]
测试数据有多组,每组的表述如下:
第一行有两个数,M和N,接下来是一个M行N列的地图,'*'表示障碍物,'.'表示走廊,'|'或者'-'表示一个楼梯,并且标明了它在一开始时所处的位置:'|'表示的楼梯在最开始是竖直方向,'-'表示的楼梯在一开始是水平方向.地图中还有一个'S'是起点,'T'是目标,0<=M,N<=20,地图中不会出现两个相连的梯子.Harry每秒只能停留在'.'或'S'和'T'所标记的格子内.
[align=left]Output[/align]
只有一行,包含一个数T,表示到达目标的最短时间.
注意:Harry只能每次走到相邻的格子而不能斜走,每移动一次恰好为一分钟,并且Harry登上楼梯并经过楼梯到达对面的整个过程只需要一分钟,Harry从来不在楼梯上停留.并且每次楼梯都恰好在Harry移动完毕以后才改变方向.
[align=left]Sample Input[/align]
5 5
**..T
**.*.
..|..
.*.*.
S....
[align=left]Sample Output[/align]
7
Hint
Hint
地图如下:
就是遇到楼梯如果对面的已经访问过,就不用走了,如果对面的没有访问过,如果能直接过,能一下子走2格,如果不能直接过,等楼梯移过来,因为这样时间跟走过去相同,
也不会多。
#include <iostream> #include <cstring> #include <string> #include <cstdio> #include <queue> using namespace std; #define maxn 25 char mp[maxn][maxn]; int vis[maxn][maxn], M, N, sx, sy, tx, ty, ans; int dir[4][2] = {{0,1}, {0,-1}, {-1,0},{1,0}}; //4个方向 struct node{ int x, y, t; }; bool judge(int x, int y){ if(x >= 0 && x < M && y >= 0 && y < N && mp[x][y] != '*' && !vis[x][y]) return 1; return 0; } bool judgeBridge(int x, int y, int t, int dir){ //注意这里要算前一秒的!!!!因为还没走 if(mp[x][y] == '|') //如果一开始是竖的话 { if(t%2==0 && (dir == 2 || dir == 3)) //如果还是竖的,且走的也是竖的 return 1 ; else if(t%2 && (dir == 0 || dir == 1)) //如果是横的而且走的也是横的, return 1 ; } else if(mp[x][y] == '-') //如果一开始是横的话 { if(t%2==0 && (dir == 0 || dir == 1)) //如果还是横的,且走的也是横的 return 1; else if(t%2 && (dir == 2 || dir == 3)) return 1; } return 0; } node q[maxn*maxn]; int BFS(int sx, int sy){ memset(vis, 0, sizeof(vis)); int front = 0, rear = 1; q[front].x = sx; q[front].y = sy; q[front].t = 0; vis[sx][sy] = 1; while(front < rear){ int x = q[front].x; int y = q[front].y; int t = q[front].t; front++; if(x == tx && y == ty) return t; //如果已经到了终点,跳出 for(int i = 0; i < 4; i++){ int nx = x+dir[i][0]; int ny = y+dir[i][1]; if(judge(nx, ny)){ if(mp[nx][ny] == '.'){ vis[nx][ny] = 1; node temp; temp.x = nx; temp.y = ny; temp.t = t+1; q[rear++] = temp; } else{ int nnx = nx + dir[i][0]; int nny = ny + dir[i][1]; //过桥 if(judge(nnx, nny)){ //如果桥对面的点没有访问过的话 if(judgeBridge(nx, ny, t,i )){ //过桥 vis[nnx][nny] = 1; node temp; temp.x = nnx; temp.y = nny; temp.t = t+1; q[rear++] = temp; } else{ //等待 node temp; temp.x = x; temp.y = y; temp.t = t+1; q[rear++] = temp; } } } } } } return -1; } int main(){ while(~scanf("%d%d", &M, &N)){ for(int i = 0; i < M; i++){ for(int j = 0; j < N; j++){ cin>>mp[i][j]; } } for(int i = 0; i < M; i++){ for(int j = 0; j < N; j++){ if(mp[i][j] == 'S'){ mp[i][j] = '.'; sx = i; sy = j; } if(mp[i][j] == 'T'){ mp[i][j] ='.'; tx = i; ty = j; } } } ans = BFS(sx, sy); printf("%d\n", ans); } return 0; }
根据这题来个BFS模板吧
int bfs(int sx,int sy) //初始位置 { memset(vis, 0 ,sizeof(vis)); //清空访问数组 int head = 0,tail=1; //头是0, 尾是1, 因为要加入一个数,就是初始位置 que[head].x=sx ,que[head].y=sy ,que[head].step = 0; //把初始位置加入队列。 vis[sx][sy] = 1 ; //初始位置标记已经访问过 while(head < tail) //当队列不为空的时候 { int x = que[head].x; int y = que[head].y; int step = que[head].step; //拿出队首元素 head++ ; //弹出 if(x == ex && y == ey) //如果已经走到终点,退出循环 { return step ; } //如果没有结束 for(int i = 0 ; i < 4 ;i++){ //走上下左右4个方向 int nx = x+d[i][0] int ny = y+d[i][1] ; if(judge(nx, ny)){ //判断满足的条件 ,如果可以走 if(map[nx][ny] == '.'){ //如果不是楼梯直接入列 vis[nx][ny] = 1 ; //标记已经访问过 que[tail].x = nx ; que[tail].y = ny ; que[tail].step = step+1 ; tail++; //加入队列 } else//如果是楼梯 { int nnx = nx + d[i][0] , nny = ny + d[i][1] ; //楼梯对面的点没有访问过 if(judge(nnx, nny)) { if(goStair(nx, ny, step,i)) //判断楼梯此时是否可走 { //如果可走则直接将该点放入队列,标记为已访问 vis[nnx][nny] = 1; que[tail].x = nnx ; que[tail].y = nny; que[tail].step = step+1 ; tail++ ; } else { //如果此时楼梯不能走,则将此时所在的点放回队尾(等待) que[tail].x = x ; que[tail].y = y ; que[tail].step = step+1 ; tail++ ; } } } } } } return -1 ; }
相关文章推荐
- HDU 1180 诡异的楼梯(BFS)
- HDU 1180 诡异的楼梯 (BFS)
- hdu 1180 诡异的楼梯【BFS+优先队列】
- hdu 1180诡异的楼梯(bfs)
- HDU 1180 诡异的楼梯(搜索 -- BFS)
- hdu 1180 诡异的楼梯 BFS 这题相当坑爹啊,需要注意几点
- HDU 1180 诡异的楼梯 BFS
- hdu 1180 诡异的楼梯 (bfs)
- HDU 1180——诡异的楼梯( BFS)
- hdu 1180 诡异的楼梯 (BFS)
- HDOJ/HDU 1180 诡异的楼梯(经典BFS-详解)
- hdu 1180:诡异的楼梯(BFS广搜)
- HDU 1180 诡异的楼梯【BFS广搜+优先队列】
- hdu1180诡异的楼梯……bfs走迷宫……wa了16次,我太渣了
- HDOJ/HDU 1180 诡异的楼梯(经典BFS-详解)
- HDU 1180:诡异的楼梯(BFS)
- HDU 1180 诡异的楼梯(BFS:时间动态图)
- hdu 1180 诡异的楼梯 (bfs)
- HDU 1180 诡异的楼梯(BFS,用优先队列过)
- HDU 1180 诡异的楼梯 BFS