您的位置:首页 > 其它

hdu1180诡异的楼梯(BFS+优先队列)

2014-04-07 09:12 316 查看
题目链接:hdu1180

/*
思路:BFS+优先队列
每当遇到楼梯的时候,
1、如果能过
a、通过楼梯后不会超出边界,则走过楼梯
b、通过楼梯后超出边界,则该点不需再入队
2、如果不能通过,时间加1,此点继续入队,等待下一次楼梯变换方向
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <cstdlib>
using namespace std;
const int inf = 0x3f3f3f3f;
const int N = 10010;
int d[4][2] = {1,0,0,1,-1,0,0,-1};
char a[25][25];
int n,m,ans,sx,sy,ex,ey;
bool v[25][25];
struct node
{
int x,y,step;
bool  operator <(const node &a) const{
return step > a.step;
}
};
bool judge(int x, int y)
{
if(x < 0 || x >= n || y < 0 || y >= m || a[x][y] == '*') return false;
return true;
}
void bfs()
{
priority_queue<node> q;
node s, tmp;
s.x = sx;
s.y = sy;
s.step = 0;
a[sx][sy] = '*';
q.push(s);
while(!q.empty())
{
tmp = q.top();
q.pop();
if(tmp.x == ex && tmp.y == ey){
printf("%d\n",tmp.step);
return;
}
for(int i = 0; i < 4; i ++){
s.x = tmp.x + d[i][0];
s.y = tmp.y + d[i][1];
if(!judge(s.x, s.y)) continue;
s.step = tmp.step+1;

if(a[s.x][s.y] == '.'){
a[s.x][s.y] = '*';
q.push(s);
}
else if(a[s.x][s.y] == '|'){
if(((tmp.step&1) == (i&1))){//人走的方向和楼梯方向相同,可以通过楼梯
if(judge(s.x+d[i][0],s.y+d[i][1])){//楼梯的另一头不会超出边界范围
s.x += d[i][0];
s.y += d[i][1];
q.push(s);
a[s.x][s.y] = a[tmp.x][tmp.y] = '*';
}//楼梯的另一头超出边界,此点不再入队
}
else{//人走的方向和楼梯方向不同,停留在原地
node ss = tmp;
ss.step ++;//时间加1
q.push(ss);
}
}
else if(a[s.x][s.y] == '-'){
if(((tmp.step&1) != (i&1))){
if(judge(s.x+d[i][0],s.y+d[i][1])){
s.x += d[i][0];
s.y += d[i][1];
q.push(s);
a[s.x][s.y] = a[tmp.x][tmp.y] = '*';
}
}
else{
node ss = tmp;
ss.step ++;
q.push(ss);
}
}
}
}
}
int main()
{
int i,j;
while(~scanf("%d%d",&n,&m))
{
for(i = 0; i < n; i ++){
scanf("%s",&a[i]);
for(j = 0; j < m; j ++){
if(a[i][j] == 'S') sx = i, sy = j;
if(a[i][j] == 'T') ex = i, ey = j,a[i][j] = '.';
}
}
bfs();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  搜索 BFS 优先队列