【分析】BFS+priority_queue(优先队列)
题意:Angel被传说中神秘的邪恶的Moligpy人抓住了!他被关在一个迷宫中。迷宫的长、宽不超过200。
迷宫中有不可以越过的墙以及监狱的看守。Angel的朋友带了一些救援队来到了迷宫中。他们的任务是:接近Angel。
我们假设接近Angel就是到达Angel所在的位置。假设移动需要1单位时间,杀死一个看守也需要1单位时间。到达一个格子以后,如果该格子有看守,则一定要杀死。
问:最少要多少单位时间,才能到达Angel所在的地方?(只能向上、下、左、右4个方向移动)
注意以下三个要点:
(1)‘a’--Angel 'r'--Angel的朋友 ‘x’--看守 ‘.’--空地(可走区域) ‘#’--障碍(不可走区域);
(2)"Angel's friends"提示我们Angel('a')只有一个,而她的朋友('r')可以有多个,因此在搜索时逆向处理一下,从天使向周围搜索,找"离她最近"的朋友;
(3)移动需要1单位时间,杀死一个看守也需要1单位时间。也就是说,搜索时遇到'.'时间+1,而遇到'x'时间+2,因此可使用优先队列(priority_queue)实现该过程。
#include
#include
#include
#include
using namespace std;
const int MAX=210;
int N,M;
int sx,sy,mint; //(sx,sy)-公主位置 mint-最少营救时间
char map[MAX][MAX];//迷宫地图
int vis[MAX][MAX]; //点的访问标记
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; //移动方向(上/下/左/右)
struct node
{
int x;
int y;
int t;
//重载'<'运算符,即定义优先队列按时间递增排序
friend bool operator <(const node &a,const node &b)
{
return (a.t>b.t);
}
} cur,nxt;
//检测当前位置(x,y)是否在迷宫内、未走过且可以走
bool check(int x,int y)
{
return (x>=0 && x=0 && y q;
//搜索起点即公主的位置
cur.x=sx;
cur.y=sy;
cur.t=0;
//将起点入队
q.push(cur);
//标记已走过(即只能走一次,以保证用时最少)
vis[cur.x][cur.y]=1;
while(!q.empty())
{
cur=q.top();
q.pop();
//找到Angel的朋友,结束整个搜索过程(此时搜出的朋友即离Angel最近的)
if(map[cur.x][cur.y]=='r')
return cur.t;
//试探当前位置(cur.x,cur.y)周围的4个位置
for(i=0;i<4;i++)
{
nxt.x=cur.x+dir[i][0];
nxt.y=cur.y+dir[i][1];
//下一位置可走
if(check(nxt.x,nxt.y))
{
//下一位置为警卫,耗时+2
if(map[nxt.x][nxt.y]=='x')
nxt.t=cur.t+2;
//否则耗时+1
else
nxt.t=cur.t+1;
//标记下一位置(nxt.x,nxt.y)已走过
vis[nxt.x][nxt.y]=1;
//将下一位置(nxt.x,nxt.y)入队
q.push(nxt);
}
}
}
return -1;
}
int main()
{
int i,j;
while(scanf("%d %d",&N,&M)!=EOF)
{
for(i=0;i