搜索—Problem_1012-Rescue
题意
营救angle,她被困在监狱里,监狱地形看作是N*M的矩阵,其中有墙,路以及卫兵。她的朋友们要去救她,只要其中任何一位朋友找到她即可。在营救过程中如果遇到卫兵需要杀死他才能通过继续前进,这种情况会用2个单位的时间,遇到墙不能走,其余的情况可以走,每移动一次消耗一个单位时间。如能营救成功,求营救的最小时间。否则输出“Poor ANGEL has to stay in the prison all his life.”
解题思路
采用BFS+优先队列。首先把问题从朋友们去营救angle转化为她去找朋友们,她可以找到任意一位朋友但所需要的时间是不同的,所以采用优先队列的方式,将找到朋友的时间排列,按最小时间进行搜索,如果顺着搜索下去可行就输出时间,不行的话换下一个路径,以此执行,实在无法完成就输出所给的话。
感想
与上课讲的例题类同,没讲之前是不容易想到用优先队列与BFS结合的,
AC代码
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
#define MAX 210
int n,m;
char map[MAX][MAX];
int visit[MAX][MAX];
int x1,x2,y1,y2;
int dir[4][2]={1,0,-1,0,0,1,0,-1,};
struct node{
int x,y,step;
friend bool operator<( node n1,node n2 )
{
return n2.step<n1.step;
}
};
bool judge(int x,int y)
{
if(x<0 || y<0 || x>=n || y>=m || !visit[x][y] || map[x][y] == '#') return true;
return false;
}
int FBS()
{
int i;
priority_queue<node> Q;
node a,next;
a.x = x1;
a.y = y1;
a.step = 0;
Q.push(a);
visit[x1][y1] = 0;
while(!Q.empty())
{
a = Q.top();
Q.pop();
if(a.x == x2 && a.y == y2)
return a.step;
for(i = 0; i<4; ++i)
{
next = a;
next.x+=dir[i][0];
next.y+=dir[i][1];
if(judge(next.x,next.y))//判断
continue;
next.step++;
if(map[next.x][next.y] == 'x')//遇到卫兵处多花费一个单位时间
next.step++;
if(visit[next.x][next.y]>=next.step)//存入最小时间
{
visit[next.x][next.y] = next.step;
Q.push(next);
}
}
}
return 0;
}
int main()
{
int i,j;
while(cin>>n>>m)
{
for(i=0;i<n;++i)
{
cin>>map[i];
for(j=0;map[i][j];++j)
{
if( map[i][j]=='r' )
{
x1=i;
y1=j;
}
else if( map[i][j]=='a' )
{
x2=i;
y2=j;
}
}
}
memset(visit,1,sizeof(visit));
int ans=0;
ans=FBS();
if(ans) cout<<ans<<endl;
else cout<<"Poor ANGEL has to stay in the prison all his life."<<endl;
}
}