题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1242
易错点:
1.判断时缺少情况,例如超出地图边界,或者漏判步数+2
2.广度优先搜索(BFC):它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止。
/*本题涉及广度优先搜索,一般与优先队列同时使用
广度优先搜索指遍历全部路径,然后找出最优路径*/
#include<stdio.h>
#include<queue>
#include<string.h>
#define maxn 210
using namespace std;
struct hell
{
int x,y;//坐标
int time;// 时间
friend bool operator<(const hell &a,const hell &b) //优先队列排序
{
return a.time>b.time;
}
};
char str[maxn][maxn];//地图定义
int n,m; //起始m,n定义
int visit[maxn][maxn];//标记经过的点
int dir[4][2]={1, 0, -1, 0, 0, 1, 0, -1};
void wide_search(int stx,int sty,int edx,int edy)
{
priority_queue<hell> q;
int ans=-1;//初始化ans用于判断终点周围是否全是墙
hell next,now;//now:现在的位置 next:下一步的位置
memset(visit,0,sizeof(visit));
now.x=stx;
now.y=sty;
now.time=0;//初始化现在的位置
visit[stx][sty]=1;
q.push(now);//将now结构体推进队列
while(!q.empty())
{
now=q.top();//更新now
q.pop();//清空队列
if(now.x==edx&&now.y==edy)
{
ans=now.time;
break;
}
for(int i=0;i<4;i++)
{
next.x=now.x+dir[i][0];
next.y=now.y+dir[i][1];//迷宫只有四种方向 上下左右;
if(next.x>=n||next.x<0||next.y<0||next.y>=m) continue;//判断next是否出界
if(visit[next.x][next.y]==1) continue;//判断next是否重复
if(str[next.x][next.y]=='#') continue;//判断next是否为墙
if(str[next.x][next.y]=='x') next.time=now.time+2;//判断next是否为 泥沼路段
else next.time=now.time+1;
q.push(next);//将next推进队列
visit[next.x][next.y]=1;//将next标记为已走过
}
}
if(ans==-1) printf("Poor ANGEL has to stay in the prison all his life.\n");
else printf("%d\n",ans);
}
int main()
{
int stx,sty,edx,edy;//起始点和终点
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=0;i<n;i++)
scanf("%s",str[i]); //输入迷宫
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(str[i][j]=='a')
{
stx=i;sty=j; //寻找起始点
}
if(str[i][j]=='r')
{
edx=i;edy=j; //寻找终点
}
}
}
wide_search(stx,sty,edx,edy);
}
return 0;
}