您的位置:首页 > 其它

HDU 1180 诡异的楼梯 bfs

2014-11-17 17:42 357 查看
题目链接
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: