题目描述就不多说了,给出地址:http://acm.hdu.edu.cn/showproblem.php?pid=1242
这道题目比较简单,可以采用DFS,也可采用深度优先搜索,上一次我们介绍了深度优先搜索
http://blog.csdn.net/zhuihunmiling/article/details/8979570
这一此我们介绍广度优先搜索
按照惯例,我们还是先说一下该题目的主要易错点
1.天使可能有多个朋友,所以不能从朋友的位置开始着天使,只能是从天使找离他最近的朋友
2.题目要求的是找到一个用时最少的朋友,而不是步数最少
既然是广度优先,那么必然用到队列,但是队列只能是先进先出,即是步数少的先遍历到,显然是不符合题目要求的,那应该怎么办呢?
c++给我们提供了标准的函数库,可以引入#include <queue> 并定义优先队列类型 priority_queue,并自动对里面的元素进行排序
如果排序不符合要求,可以给出小于号 “<” 的运算符重载函数,当然在结构体里面进行了,代码里面有具体的实现
广度优先搜索依然是简单的 出队--》判断--》扫描---》入队 的四部曲。结构简单,程序也容易实现,现直接给出代码实现
#include <iostream> #include <stdio.h> #include <string.h> #include <queue> #define N 201 using namespace std; //优先队列解决,广度优先 struct Persion { int x,y; int time; friend bool operator < (const Persion &a,const Persion &b) { return a.time>b.time; //">" 返回队列中较小的元素;"< " 则返回队列中较大的元素 } }; int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; char map[N][N]; int visited[N][N]; int m,n; int BFS(int x,int y) { priority_queue <Persion>q; Persion current,next; memset(visited,0,sizeof(visited)); current.x=x; current.y=y; current.time=0; visited[current.x][current.y]=1; q.push(current); while(!q.empty()) { current=q.top(); q.pop(); for(int i=0;i<4;i++) { next.x=current.x+dir[i][0]; next.y=current.y+dir[i][1]; if(next.x>=0&&next.x<n&&next.y>=0&&next.y<m&&map[next.x][next.y]!='#'&&!visited[next.x][next.y]) { if(map[next.x][next.y]=='r') return current.time+1; if(map[next.x][next.y]=='x') next.time=current.time+2; else next.time=current.time+1; visited[next.x][next.y]=1; q.push(next); } } } return -1; } int main() { int i,j; Persion angle; while(cin>>n>>m&&(m||n)) { for(i=0;i<n;i++) for(j=0;j<m;j++) { cin>>map[i][j]; if(map[i][j]=='a') { angle.x=i; angle.y=j; } } int time=BFS(angle.x,angle.y); if(time==-1) cout<<"Poor ANGEL has to stay in the prison all his life."<<endl; else cout<<time<<endl; } return 0; }