码迷,mamicode.com
首页 > 其他好文 > 详细

Rescue(BFS时间最短)

时间:2018-07-23 17:23:50      阅读:108      评论:0      收藏:0      [点我收藏+]

标签:using   代码   ogr   sum   表示   start   最小   cal   使用   

Angel was caught by the MOLIGPY! He was put in prison by Moligpy. The prison is described as a N * M (N, M <= 200) matrix. There are WALLs, ROADs, and GUARDs in the prison.

Angel‘s friends want to save Angel. Their task is: approach Angel. We assume that "approach Angel" is to get to the position where Angel stays. When there‘s a guard in the grid, we must kill him (or her?) to move into the grid. We assume that we moving up, down, right, left takes us 1 unit time, and killing a guard takes 1 unit time, too. And we are strong enough to kill all the guards.

You have to calculate the minimal time to approach Angel. (We can move only UP, DOWN, LEFT and RIGHT, to the neighbor grid within bound, of course.)



Input

First line contains two integers stand for N and M.

Then N lines follows, every line has M characters. "." stands for road, "a" stands for Angel, and "r" stands for each of Angel‘s friend.

Process to the end of the file.


Output

For each test case, your program should output a single integer, standing for the minimal time needed. If such a number does no exist, you should output a line containing "Poor ANGEL has to stay in the prison all his life."


Sample Input

7 8
#.#####.
#.a#..r.
#..#x...
..#..#.#
#...##..
.#......
........


Sample Output

13

 

 

 

题目意思:Angel被抓住了,关在监狱里面,他的朋友想要去营救他,他的朋友可以上下左右移动一步,每移动一步耗时一个时间单位,监狱里还有警卫x,杀死一个警卫也要耗时一个时间单位,监狱里面还有不能走的围墙#,求他的朋友找到Angel至少需要多少时间。

解题思路:我们知道BFS适合用来求最短路,求出来的解是步数最少的解,但是这道题步数最少的解并不是最优解,我们会发现在BFS扩展节点时,单纯遇到守卫就直接对步数加一是不影响从r到a的距离的,想到这里,单纯的BFS好像就不行了,这里就需要对BFS进行一些处理,这里我们再定义一个数组mintime,mintime[i][j]代表Angel朋友走到(i,j)位置所需要的最少时间,在BFS搜索过程中,从当前位置走到临近位置(x,y)时,只有当这种走法比之前走到(x,y)位置所花时间更少,才会把当前走到(x,y)位置所代表表示的状态入队列,否则是不会入队列的。在本代码中并没有使用标明各个位置是否访问过的状态数组vis,也没有在BFS过程中将访问过的相邻位置设置为不可再访问,但BFS也不会无限搜索下去,因为从某个位置出发判断是否需要将它的相邻位置(x,y)入队列时,条件是这种走法比之前走到(x,y)位置所花时间更少;如果所花时间更少,则(x,y)位置会重复入队,但不会无穷下去,因为到达(x,y)位置的最少时间肯定是有下界的。

 

 

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<queue>
  4 #include<algorithm>
  5 #define INF 0x3f3f3f3f
  6 using namespace std;
  7 int n,m;
  8 struct point
  9 {
 10     int x;
 11     int y;
 12     int step;
 13     int time;
 14 };
 15 queue<point>q;
 16 char maps[210][210];
 17 int mintime[210][210];///走到每个位置所需的最少时间
 18 int dix[4]= {1,-1,0,0};
 19 int diy[4]= {0,0,1,-1};
 20 int ax,ay;///Angel位置
 21 int judge(int x,int y)///判断能否移动到相邻的位置
 22 {
 23     if(x>=0&&x<n&&y>=0&&y<m&&maps[x][y]!=#)///排除边界和墙
 24     {
 25         return 1;
 26     }
 27     return 0;
 28 }
 29 int BFS(point s)
 30 {
 31     int i,a,b;
 32     q.push(s);
 33     point hd;
 34     while(!q.empty())
 35     {
 36         hd=q.front();
 37         q.pop();
 38         for(i=0; i<4; i++)
 39         {
 40             a=hd.x+dix[i];
 41             b=hd.y+diy[i];
 42             if(judge(a,b))
 43             {
 44                 point t;///向第i方向后走一步的位置
 45                 t.x=a;
 46                 t.y=b;
 47                 t.step=hd.step+1;
 48                 t.time=hd.time+1;
 49                 if(maps[a][b]==x)
 50                 {
 51                     t.time++;///杀死守卫多花一个时间单位
 52                 }
 53                 if(t.time<mintime[a][b])
 54                 {
 55                     mintime[a][b]=t.time;
 56                     q.push(t);
 57                 }
 58             }
 59         }
 60     }
 61     return mintime[ax][ay];
 62 }
 63 int main()
 64 {
 65     int i,j,mint;
 66     int sx,sy;
 67     point start;
 68     while(scanf("%d%d",&n,&m)!=EOF)
 69     {
 70         getchar();
 71         memset(maps,0,sizeof(maps));
 72         for(i=0; i<n; i++)
 73         {
 74             for(j=0; j<m; j++)
 75             {
 76                 scanf("%c",&maps[i][j]);
 77                 mintime[i][j]=INF;
 78                 if(maps[i][j]==a)
 79                 {
 80                     ax=i;
 81                     ay=j;
 82                 }
 83                 if(maps[i][j]==r)
 84                 {
 85                     sx=i;
 86                     sy=j;
 87                 }
 88             }
 89             getchar();
 90         }
 91         start.x=sx;
 92         start.y=sy;
 93         start.step=0;
 94         start.time=0;
 95         mintime[sx][sy]=0;
 96         mint=BFS(start);
 97         if(mint<INF)
 98         {
 99             printf("%d\n",mint);
100         }
101         else
102         {
103             printf("Poor ANGEL has to stay in the prison all his life.\n");
104         }
105     }
106     return 0;
107 }

 

 

因为看到数据量并不是很大,这道题我之前也试图使用DFS穷举加上一些剪枝来解决,可是时间超限,不过这次对DFS和BFS也有了一些新的理解了

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 int n,m;
 6 char maps[210][210];
 7 int vis[210][210];
 8 int dix[4]={1,-1,0,0};
 9 int diy[4]={0,0,1,-1};
10 int ans;///记录最小耗时
11 int flag;///记录是否能够找到天使
12 void my_dfs(int x,int y,int time)///time记录所用的时间
13 {
14     int i,a,b;
15     if(maps[x][y]==#||vis[x][y]==1)
16     {
17         return ;
18     }
19     if(time>=ans)///此处为一次剪枝
20     {
21         return ;
22     }
23     if(maps[x][y]==r)
24     {
25         flag=1;
26         if(time<ans)///找到最短的通路
27         {
28             ans=time;
29         }
30         return ;
31     }
32     if(maps[x][y]==x)
33     {
34         time++;
35     }
36     vis[x][y]=1;
37     for(i=0;i<4;i++)
38     {
39         a=x+dix[i];
40         b=y+diy[i];
41         my_dfs(a,b,time+1);
42     }
43     vis[x][y]=0;///消去标记
44 }
45 int main()
46 {
47     int i,j,x,y;
48     while(scanf("%d%d%",&n,&m)!=EOF)
49     {
50         getchar();
51         memset(maps,#,sizeof(maps));
52         memset(vis,0,sizeof(vis));
53         for(i=1;i<=n;i++)
54         {
55             for(j=1;j<=m;j++)
56             {
57                 scanf("%c",&maps[i][j]);
58                 if(maps[i][j]==a)
59                 {
60                     x=i;
61                     y=j;
62                 }
63             }
64             getchar();
65         }
66         flag=0;
67         ans=200*200;///迷宫规模
68         my_dfs(x,y,0);
69         if(flag)
70         {
71             printf("%d\n",ans);
72         }
73         else
74         {
75             printf("Poor ANGEL has to stay in the prison all his life.\n");
76         }
77     }
78     return 0;
79 }

 

 

Rescue(BFS时间最短)

标签:using   代码   ogr   sum   表示   start   最小   cal   使用   

原文地址:https://www.cnblogs.com/wkfvawl/p/9355500.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!