救援行动(save)
题目描述
Angel被人抓住关在一个迷宫了!迷宫的长、宽均不超过200,迷宫中有不可以越过的墙以及监狱的看守。Angel的朋友带了一个救援队来到了迷宫中。他们的任务是:接近Angel。我们假设接近Angel就是到达Angel所在的位置。
假设移动需要1单位时间,杀死一个看守也需要1单位时间。到达一个格子以后,如果该格子有看守,则一定要杀死。交给你的任务是,最少要多少单位时间,才能到达Angel所在的地方(只能向上、下、左、右4个方向移动)?
输入
第1行两个整数n,m。表示迷宫的大小为n×m。
以后n行,每行m个字符。其中“#”代表墙,“.”表示可以移动,“x”表示看守,“a”表示Angel,“r”表示救援队伍。字母均为小写。
输出
l行,代表救出Angel的最短时间。如果救援小组永远不能达到Angel处,则输出“NO ANSWER”。
样例输入
7 8
#.#####.
#.a#..r.
#..#x...
..#..#.#
#...##..
.#......
........
样例输出
13
这个地方当遇到x时,相当于走了两步,故可能先走到a时,是经过x的,但这样就与想要的结果有差别,故所以用优先队列可以让先不经x的先到a。
#include <vector> #include <cstdio> #include <algorithm> #include <queue> #include <cstring> #define fi first #define se second #define md make_pair using namespace std; const int inf=0x3f3f3f3f; typedef pair<int,int> pi; char maze[205][205]; int sx,sy,gx,gy,m,n; int d[205][205]; int dx[4] = {1,0,-1,0},dy[4]={0,1,0,-1}; int bfs(){ int flag=0; priority_queue<pair<int,pi>,vector<pair<int,pi> >,greater<pair<int,pi> > > que; memset(d,0x3f,sizeof(d)); //d[gx][gy]=inf; d[gx][gy]=0; que.push(md(0,md(gx,gy))); while(!que.empty()){ pair<int,pi> p =que.top();que.pop(); if(p.se.fi==sx&&p.se.se==sy) {flag=1;break;} for(int i=0;i<4;i++){ int nx=p.se.fi+dx[i],ny=p.se.se+dy[i]; if((nx>=0&&nx<n&&ny>=0&&ny<m&&maze[nx][ny]!='#'&&d[nx][ny]==inf)){ if(maze[nx][ny]=='x') d[nx][ny]=d[p.se.fi][p.se.se]+2; else d[nx][ny]=d[p.se.fi][p.se.se]+1; que.push(md(d[nx][ny],md(nx,ny))); } } } if(flag) return d[sx][sy]; else return -1; } int main(){ //freopen("data.in","r",stdin); scanf("%d%d",&n,&m); getchar(); for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ scanf("%c",&maze[i][j]); if(maze[i][j]=='r')sx=i,sy=j; if(maze[i][j]=='a')gx=i,gy=j; } if(i!=n-1)getchar(); } //printf("%d %d %d %d",sx,sy,gx,gy); int res=bfs(); if(res!=-1) printf("%d\n",res); else printf("NO ANSWER\n"); }