hdoj 1180 搜索 + bfs + 优先队列

题目


#include<iostream>
#include<queue>
#define MAX 22
#include<string.h>
using namespace std;

struct Node{
	int x, y, s;
	friend bool operator<(const Node &a, const Node &b){
		return a.s > b.s;
	}
};

int vis[MAX][MAX];
char c;
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
int n, m;
int sx, sy;
char map[MAX][MAX];
int check(int x, int y){
	if(x>=0 && x<n && y>=0 && y<m && !vis[x][y] && map[x][y]!='*')
		return 1;
	return 0;	
}
Node t1, t2, node;
int bfs(int x, int y){
	priority_queue<Node> pq;
	node.x = x; node.y = y; node.s = 0;
	pq.push(node);
	vis[node.x][node.y] = 1;//标记已经访问
	while(!pq.empty()){
		t1 = pq.top();
		pq.pop();
		if(map[t1.x][t1.y] == 'T') 
			return t1.s;
		//if(map[t2.x][t2.y] == 'T') return t2.s;
		for(int i = 0; i < 4; ++i){
			int nx = t1.x + dir[i][0];
			int ny = t1.y + dir[i][1];
			if(!check(nx,ny)) continue;
			t2.x = nx; t2.y = ny; t2.s = t1.s+1;
			//下一位置是楼梯时候才考虑 否则正常走 
			//有楼梯时*********************************
			if(map[nx][ny] == '|' || map[nx][ny] == '-'){
				if(t2.s%2 == 0){ //这里为偶数步时候 其之前一步的楼梯应该反向  
					if(map[nx][ny] == '|')
						c = '-';
					else if(map[nx][ny] == '-')
						c = '|';	
				}
				else
					c = map[nx][ny];
				t2.x += dir[i][0];
				t2.y += dir[i][1];
				if(!check(t2.x,t2.y)) continue;
				if(c == '|' && (dir[i][1] == 1 || dir[i][1] == -1) || c == '-'&& (dir[i][0] == 1 || dir[i][0] == -1)){
					t2.s += 1;//c表示到达楼梯前一步时候楼梯所处的状态			
				}			//如果人沿着x(上下)走 楼梯横着 等待
							//人沿着y(左右)走 楼梯 竖着等待 
			}
		//***********************************	
                vis[t2.x][t2.y] = 1;
                pq.push(t2);
		}	
	}//end OF while 
	return -1;	
}

int main()
	{
		while(scanf("%d%d",&n,&m)!=EOF){
			for(int i = 0; i < n; ++i){
				for(int j = 0; j < m; ++j){
					cin >> map[i][j];
					if(map[i][j] == 'S'){
 						sx = i; sy = j; 
 					}
				}
			}
			memset(vis,0,sizeof(vis));
			int ans = bfs(sx, sy);
			printf("%d\n",ans);
		}	
		
		return 0;
	}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值