bfs解决hdu1242Rescue

Rescue

题目链接

题目描述

具体请点击上方题目链接。题目大概意思就是给定一个n和m,然后给定一个由"#", “.” , “a” , “x” , “r” 构成的矩阵。然后要求从r到a的所需的最短的时间。

解题思路

需要注意的是"#“表示墙壁,不可通过,”."表示可通过,"a"表示要到达的目的地,"x"表示警官的位置,必须先耗费一定时间将将官杀掉,然后才能通过,“r"表示朋友所在位置,即开始的位置,但是题目中说"r” stands for each of Angel’s friend,说明可能会有好几个朋友,那我们只需要转化一下,变成从a开始找到最近的一个r就可以了。

bfs的思路就是从a所在位置开始,分别向上下左右走一步,看看是否满足条件(是否可以通过即不为#,该点是否已经走过,该点是否在图内部),然后将新节点的状态压入到队列中就可以了。 需要注意的是 需要用到优先队列,因为遇到x时 是需要耗费2,而遇到.的话 只需要耗费1,所以每个节点的权值是不同的,我们要保证每次的首节点权值是队列中最小的一个,才能保证获得最小值。

代码如下

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;

struct node {
	int x,y;
	int step;
	friend bool operator < (node a,node b) {
		return a.step>b.step;
	}
};
char s[205][205];
bool vis[205][205];
int n,m;
int sx,sy;//a所在的坐标
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};//四个方向
int ans;
void bfs() {
	priority_queue<node>q;
	node start;//初状态
	start.x = sx;
	start.y = sy;
	start.step = 0;
	vis[sx][sy] = true;
	q.push(start);
	while(!q.empty()) {
		node top = q.top();
		q.pop();
		if(s[top.x][top.y] == 'r') {//结束条件
			ans = top.step;
			return;
		}
		for(int i = 0; i< 4; i++) {//遍历四个方向
			int r = top.x + dir[i][0];
			int c = top.y + dir[i][1];
			if(r>=0 && r<n && c>=0 && c<m && !vis[r][c] && s[r][c]!='#') {
				node now = top;
				now.x = r;
				now.y = c;
				if(s[r][c] == 'x') now.step+=2;
				else now.step++;//r和.
				vis[r][c] = true;//标记走过该点
				q.push(now);
			}
		}
	}
	return;
}
int main() {
	while(scanf("%d%d",&n,&m)!=EOF) {//多样例
		ans = -1;//初始化
		for(int i = 0; i< n; i++) {
			scanf("%s",s[i]);
			for(int j = 0; j< m; j++) {
				if(s[i][j] == 'a') {
					sx = i;
					sy = j;
				}
			}
		}
		memset(vis,false,sizeof(vis));
		bfs();
		if(ans != -1) printf("%d\n",ans);
		else printf("Poor ANGEL has to stay in the prison all his life.\n");
	}
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值