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;
}