HDU1242 Rescue

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1242

参考博文1:http://blog.csdn.net/iaccepted/article/details/23101875

参考博文2:http://blog.csdn.net/libin56842/article/details/9039351

该题类似于走迷宫,但不完全是,因为在走的过程中会遇到警察,可以选择杀死警察,但要付出相应的代价,时间加1。用走迷宫的算法只是能找到angle到队友最短的那条路径,但所用时间不一定是最短。因为用visit数组对地点进行标记后,再从其它点出发访问到该点时,由于位置已经被访问过,将不再把该点入队列(即使在这种情况下所用的实际时间比较上一次访问该点时所用的时间少)。因此需要对visit数组加以改造,当访问到该点时,把所走的路径长度存储到其中,当下次再次走到该点时先比较路径长度,再决定是否将该点进行入队操作。

 1 #include <iostream>
 2 #include <queue>
 3 #include <stdio.h>  
 4 #include <cstring>
 5 using namespace std;
 6 #define MAX 201
 7 //存储地图 
 8 char G[MAX][MAX];
 9 //访问标记数组,存储到达改点时的最短路径长度 
10 int visit[MAX][MAX];
11 //四个方向 
12 int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
13 int n,m;
14 //定义节点类型 
15 struct POS{
16     int x,y,step;
17     friend bool operator< (const POS &a,const POS &b){
18         return a.step>b.step;
19     }
20 };
21 //检测节点是否合法 
22 bool check(POS p){
23     //检查边界
24     //!visit[p.x][p.y]检查是否为初始节点
25     //检查是否是墙 
26     if(p.x<0||p.x>=n||p.y<0||p.y>=m||!visit[p.x][p.y]||G[p.x][p.y]=='#')
27         return 1;
28     return 0;
29 }
30 int main(){
31     while(cin>>n>>m&&(m||n)){
32         memset(visit,1,sizeof(visit));
33         //开始点'a',为angle的位置 
34         POS start;
35         for(int i=0;i<n;i++)
36             for(int j=0;j<m;j++){
37                 cin>>G[i][j];
38                 if(G[i][j]=='a'){
39                     start.x=i; start.y=j;
40                 }
41             }
42         start.step=0;
43         visit[start.x][start.y]=0;
44         //使用优先级队列 
45         priority_queue<POS> bfs;
46         //普通队列 
47         //queue<POS> bfs; 
48         //首元素入队列 
49         bfs.push(start);
50         POS t;
51         //开始bfs 
52         while(!bfs.empty()){
53             //取首元素 进行验证 
54             //t=bfs.front();
55             t=bfs.top();
56             bfs.pop();
57             char ch=G[t.x][t.y];
58             if(ch=='r'){
59                 cout<<t.step<<endl;
60                 break;
61             }
62             
63             //遍历当前节点的四个邻接点 
64             POS temp;
65             for(int i=0;i<4;i++){
66                 temp=t;
67                 temp.x+=dir[i][0];
68                 temp.y+=dir[i][1];
69                 //检验节点的合法性 
70                 if(check(temp))
71                     continue;
72                 temp.step++;
73                 //遇到警察步数加1 
74                 if(G[temp.x][temp.y]=='x')
75                     temp.step++;
76                 //如果当前到达该点的步数比上一次的步数少或者等于上一次的步数,则入队列 
77                 if(visit[temp.x][temp.y]>=temp.step){
78                     bfs.push(temp);
79                     visit[temp.x][temp.y]=temp.step;
80                 }
81                 
82             }
83         }
84         if(bfs.empty())
85             cout<<"Poor ANGEL has to stay in the prison all his life.\n";
86     }
87     return 0;
88 }

 

posted @ 2017-03-27 22:39  茄阁云云  阅读(293)  评论(0编辑  收藏  举报