1224. 简单迷宫问题

单点时限: 2.0 sec

内存限制: 256 MB

一天,sunny 不小心进入了一个迷宫,不仅很难寻找出路,而且有的地方还有怪物,但是 sunny 有足够的能力杀死怪物,但是需要一定的时间,但是 sunny 想早一点走出迷宫,所以请你帮助他计算出最少的时间走出迷宫,输出这个最少时间。

我们规定每走一格需要时间单位 1, 杀死怪物也需要时间 1, 如果不能走到出口,则输出 impossible. 每次走只能是上下左右 4 个方向。

输入格式
每次首先 2 个数 n,m (0<n,m≤200),代表迷宫的高和宽,然后 n 行,每行 m 个字符。

S 代码你现在所在的位置。
T 代表迷宫的出口。

代表墙,你是不能走的。

X 代表怪物。
. 代表路,可以走。
处理到文件结束。

输出格式
输出最少的时间走出迷宫。不能走出输出 impossible。

样例
input
4 4
S.X.
#…#
…#.
X…T
4 4
S.X.
#…#
…#.
X.#T
output
6
impossible

/*
思路:一般的bfs基础上加入了优先级,故使用优先队列。
*/
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
int x[4]= {1,-1,0,0};
int y[4]= {0,0,1,-1};
bool visit[200][200]= {false};
int n,m;
int e1,e2;
char s[200][200];
struct g {
	int x,y;
	int len;
	friend bool operator < (g a,g b) {
		return a.len>b.len;
	}
};
bool text(int a,int b) {
	if(a<0||b<0||a>=n||b>=m||visit[a][b]||s[a][b]=='#')
		return false;
	return true;
}
void bfs(int a,int b) {
	g G;
	G.x=a;
	G.y=b;
	G.len=0;
	visit[a][b]=true;
	priority_queue<g>q;
	q.push(G);
	while(!q.empty()) {
		g f = q.top();
		q.pop();
		//	cout<<f.x<<" "<<f.y<<endl;
		if(f.x==e1&&f.y==e2) {
			cout<<f.len<<endl;
			return;
		}
		for(int i = 0; i < 4; i++) {
			a=f.x+x[i];
			b=f.y+y[i];
			if(text(a,b)) {
				g h;
				h.x=a;
				h.y=b;
				visit[a][b]=true;
				if(s[a][b]=='X')
					h.len=f.len+2;
				else
					h.len=f.len+1;
				q.push(h);
			}
		}
	}
	cout<<"impossible"<<endl;
}
int main() {
	int f1,f2;
	while(cin>>n>>m) {
		memset(visit,0,sizeof(visit));
		for(int i = 0; i< n; i++) {
			for(int j = 0; j < m; j++) {
				cin>>s[i][j];
				if(s[i][j]=='S') {
					f1=i;
					f2=j;
				}
				if(s[i][j]=='T') {
					e1=i;
					e2=j;
				}
			}
		}
		bfs(f1,f2);
	}
	return 0;
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值