zoj 1649 Rescue ——BFS入门题

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=649

题意:

  给一个字符矩阵,‘#’代表墙壁,’.’代表空格,‘x’代表有警察的空格,’r’和’a’分别代表一屌丝,并且’r’要到’a’那里去串门儿,r走一个空格花费单位时间1,走一个有警察的空格需要先干掉警察,话费单位时间1,然后再走过去,也就是共花费时间2,请问屌丝r到屌丝a那里去最少花费的时间。

思路:

  首先要搞明白一个问题:就是路径最短的路不一定花费时间最少。这是可以理解的,比如,一条很短但是有很多警察,另一条路很长,但是没有警察,很有可能是第二条路花费时间少。用深搜?貌似不太合适,因为你一条路径访问过一个点后,另一条路径很可能也会访问这个点,并且时间较少。关键是深搜找到的接不一定是最优的。所以,考虑用广搜解。这道题最朴素的广搜显然不行,也就是说,仅仅求步数最少的不可行,需要加上访问时间这个附加条件。

  用一个结构体数组存储每个点的信息,包括坐标,到达这个点所需要的最短时间,从起点开始搜,先访问起点,然后把起点出队,如果从一个点A到达下一个点B的当前所需时间比这个点现在标记的时间少,则把这个点入队,然后判断点A的另一个方向上的下一个点。这样,总有一天队列会为空,这是因为,某个点不可能被访问无数次,也就是说,某个点不可能无数次入队,因为到达某个点所需要的时间一定是有个最小值的,所以BFS一定可以结束,并且最后找到的点‘a’的信息一定是最优解。输出就可以了,如果无解,因为初始化到达所有点所需时间都是MAXN,所以,如果点‘a’的时间信息如果等于MAXN,那么说明无解。

  第一次做深搜,这道题开始不知道怎么做,看了书上的思路,坚持没看代码,自己又想了想,就试着开始写,好神奇,竟然1A了!!!

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cctype>
 6 #include <stack>
 7 #include <queue>
 8 #include <cmath>
 9 #include <algorithm>
10 #define lson l, m, rt<<1
11 #define rson m+1, r, rt<<1|1
12 using namespace std;
13 typedef long long int LL;
14 const int MAXN =  0x3f3f3f3f;
15 const int  MINN =  -0x3f3f3f3f;
16 const double eps = 1e-9;
17 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1},
18   {1,1},{1,-1},{-1,-1}};
19 
20 typedef struct point{
21   int a, b, t;
22 }point;
23 point p[220][220], st, en;
24 char s[220][220];
25 int n, m, T, si, sj, di, dj; 
26 queue<point> qt;
27 void bfs(){
28   qt.push(st);
29   while (!qt.empty()){
30     point po = qt.front();
31     qt.pop();
32     for (int k = 0; k < 4; ++k){
33       int nexti=po.a+dir[k][0],nextj=po.b+dir[k][1];
34       if (nexti>=0&&nexti<=n&&nextj>=0&&nextj<=m&&s[nexti][nextj]!='#'){
35         int nowt = po.t+1; if(s[nexti][nextj]=='x') nowt++;
36         if (nowt<p[nexti][nextj].t){
37           p[nexti][nextj].t = nowt;
38           qt.push(p[nexti][nextj]);
39         }
40       }
41     }
42   }
43 }
44 int main(void){
45 #ifndef ONLINE_JUDGE
46   freopen("zoj1649.in", "r", stdin);
47 #endif
48   while (~scanf("%d%d", &n, &m)){
49     getchar();
50     for (int i = 1; i <= n; ++i){
51       for (int j = 1; j <= m; ++j){
52         scanf("%c", &s[i][j]);
53         if (s[i][j] == 'r') {si = i; sj = j;}
54         else if (s[i][j] == 'a') {di = i; dj = j;}
55         p[i][j].t = MAXN; p[i][j].a = i; p[i][j].b = j;
56       } getchar();
57     }
58     st.a = si; st.b = sj; st.t = 0;
59     bfs();
60     if (p[di][dj].t == MAXN){
61       printf("Poor ANGEL has to stay in the prison all his life.\n");
62     } else printf("%d\n", p[di][dj].t);
63   }
64 
65   return 0;
66 }

虽然写的代码还是有点儿挫,但是第一次做就写对了,信心大增,做题好久没有这么爽了!

不过仔细想想,这题确实思路也不难,一次做对是应该的,没什么可得意的……o(╯□╰)o

    原文作者:BFS
    原文地址: https://www.cnblogs.com/liuxueyang/archive/2013/04/08/3008768.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞