7 8 #.#####. #.a#..r. #..#x... ..#..#.# #...##.. .#...... ........
13
BFS广搜 + 优先队列。
题意:从前有一名天使被囚禁了,天使的朋友要去救他,你的任务是输出最短的救援时间。天使的朋友每秒可以走一步,地牢中有守卫,当你遇到守卫的时候需要停留一秒杀死守卫。给你地牢的地图,上面有几种元素,'.'表示路,可以通行。'#'代表墙,无法通行。'r'表示天使的朋友,代表起点。'a'表示天使的位置,代表终点。'x'表示守卫的位置。
思路:因为是求“最短路径”的问题,正好用广搜可以解决。但是与普通广搜不同的是,遇到守卫的时候会多停留一秒。这就会导致队列中优先级的不稳定,所以需要用优先队列,让优先级最高的节点始终在队列最前面。
代码:
1 #include <iostream>
2 #include <string.h>
3 #include <queue>
4 using namespace std; 5 char a[201][201]; 6 bool isv[201][201]; //记录访问过没有
7 int dx[4] = {0,1,0,-1}; 8 int dy[4] = {1,0,-1,0}; 9 int N,M; 10 int sx,sy,ex,ey; 11 struct NODE{ 12 int x; 13 int y; 14 int step; 15 friend bool operator < (NODE n1,NODE n2) //自定义优先级。在优先队列中,优先级高的元素先出队列。
16 { 17 return n1.step > n2.step; //通过题意可知 step 小的优先级高,需要先出队。
18 } 19 }; 20 bool judge(int x,int y) 21 { 22 if( x<1 || y<1 || x>N || y>M ) 23 return 1; 24 if( isv[x][y] ) 25 return 1; 26 if( a[x][y]=='#' ) 27 return 1; 28 return 0; 29 } 30 int bfs() //返回从(x,y)开始广搜,到右下角的最短步数,如果无法到达右下角,返回0
31 { 32 memset(isv,0,sizeof(isv)); 33 priority_queue <NODE> q; //定义一个优先队列
34 NODE cur,next; 35 cur.x = sx; 36 cur.y = sy; 37 cur.step = 0; 38 isv[sx][sy] = true; 39 q.push(cur); //第一个元素入队
40 while(!q.empty()){ 41 cur = q.top(); //队首出队,注意不是front()
42 q.pop(); 43 if(cur.x==ex && cur.y==ey) //到终点
44 return cur.step; 45 for(int i=0;i<4;i++){ 46 int nx = cur.x + dx[i]; 47 int ny = cur.y + dy[i]; 48 if( judge(nx,ny) ) //判定
49 continue; 50 //可以走
51 next.x = nx; 52 next.y = ny; 53 if(a[nx][ny]=='x') 54 next.step = cur.step + 2; 55 else
56 next.step = cur.step + 1; 57 isv[nx][ny] = true; 58 q.push(next); 59 } 60 } 61 return -1; 62 } 63 int main() 64 { 65 while(cin>>N>>M){ 66 for(int i=1;i<=N;i++) //输入
67 for(int j=1;j<=M;j++){ 68 cin>>a[i][j]; 69 if(a[i][j]=='a') 70 ex=i,ey=j; 71 else if(a[i][j]=='r') 72 sx=i,sy=j; 73 } 74 int step = bfs(); 75 if(step==-1) //不能到达
76 cout<<"Poor ANGEL has to stay in the prison all his life."<<endl; 77 else
78 cout<<step<<endl; 79 } 80 return 0; 81 }
Freecode : www.cnblogs.com/yym2013