HDU 1180 诡异的楼梯 bfs
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=1180
题目分析:
这个是要我们找最短的时间,一般遇到此类问题都是要用BFS来做的。
因为这个地图是会变换的,因此我们要存储他不同时刻的地图,然后根据时刻来确定要用到哪个地图。
首先是我们要确定入栈节点的所需要的属性。
坐标 x, y
当前的状态 s 用来确定当前的要用哪一个地图
时间 time
此外我们还要用到标记数组 vis[地图][x][y]
用来判断这个点是否入过栈, 否则会爆栈的
#include <iostream> #include <vector> #include <stack> #include <cstdlib> #include <cmath> #include <cstdio> #include <cstring> #include <string> #include <queue> using namespace std; #define maxn 120 #define INF 0xffffff struct Point { int x, y; int time; int s; }Ps, Pe; int dir[5][2] = { {0,0},{1,0},{-1,0},{0,1},{0,-1} }; char maps[2][maxn][maxn]; bool vis[2][maxn][maxn]; int m, n; bool OK(Point P) { return P.x >= 0 && P.x < m&& P.y >= 0 && P.y < n && maps[P.s][P.x][P.y] != '*' ; } int BFS() { Point Pn, P; queue<Point> Q; Q.push(Ps); vis[Ps.s][Ps.x][Ps.y] = true; while( !Q.empty() ) { P = Q.front(); Q.pop(); if( P.x == Pe.x && P.y == Pe.y ) return P.time; for(int i=0; i<5; i++) { Pn = P; Pn.x = P.x + dir[i][0]; Pn.y = P.y + dir[i][1]; Pn.s ^= 1; Pn.time ++; if( OK(Pn) && maps[Pn.s][Pn.x][Pn.y] == '.' && !vis[Pn.s][Pn.x][Pn.y]) { vis[Pn.s][Pn.x][Pn.y] = true; Q.push(Pn); } else if( (maps[Pn.s^1][Pn.x][Pn.y] == '|' && i <= 2 && i >= 1 ) || (maps[Pn.s^1][Pn.x][Pn.y] == '-' && i >= 3) ) { Pn.x += dir[i][0]; Pn.y += dir[i][1]; if( OK(Pn) && !vis[Pn.s][Pn.x][Pn.y]) { Q.push(Pn); vis[Pn.s][Pn.x][Pn.y] = true; } } } } return -1; } int main() { while(cin >> m >> n) { memset(vis,0,sizeof(vis)); for(int i=0; i <m; i++) { cin >> maps[0][i]; for(int j=0; j<n; j++) { if(maps[0][i][j] == 'S') Ps.x = i, Ps.y = j, Ps.time = 0, maps[0][i][j] = '.', Ps.s = 0; if(maps[0][i][j] == 'T') Pe.x = i, Pe.y = j, maps[0][i][j] = '.'; if(maps[0][i][j] == '|') maps[1][i][j] = '-'; else if(maps[0][i][j] == '-') maps[1][i][j] = '|'; else maps[1][i][j] = maps[0][i][j]; } } int ans = BFS(); cout << ans << endl; } return 0; }