zoukankan      html  css  js  c++  java
  • ZOJ 1649 Rescue BFS/优先队列

    在HDOJ上提交通过以后,再在zoj上提交,结果得到了无数个WA,后来发现有一种情况我并没有考虑到


     有几个关键的地方需要注意:

    1. Angel的朋友不只有一个,可能有多个

    2. guard的存在可能会破坏广度优先树


    解决办法:

    BFS的做法:必须要保存guard与可行点‘.’的插入同步,因为guard的costTime不同,应该先不改变其坐标,costTime增加一以后,设为已被访问,‘x’变为‘.’或者‘#’,重新入队,此时,guard已被插入到队列的尾部,这样一来,guard与‘.’就可以同步了

    View Code
      1 #include <math.h>
    2 #include <stdio.h>
    3 #include <stdlib.h>
    4 #include <string.h>
    5 #include <memory.h>
    6
    7 char maze[210][210];
    8 int vis[210][210];
    9 int dx[] = {-1, 1, 0, 0};
    10 int dy[] = {0, 0, -1, 1};
    11 int nNum, mNum, i, j, sx, sy;
    12
    13 struct Node
    14 {
    15 int x;
    16 int y;
    17 int step;
    18 };
    19
    20 int IsInBound(int x, int y)
    21 {
    22 if (x<0 || y<0 || x>=nNum || y>=mNum)
    23 {
    24 return 0;
    25 }
    26
    27 return 1;
    28 }/* IsInBound */
    29
    30 void BFS()
    31 {
    32 int k;
    33 int front = -1;
    34 int rear = -1;
    35 int isSolve = 0;
    36 struct Node dir, cur;
    37 struct Node q[40010] = {0};
    38
    39 cur.x = sx;
    40 cur.y = sy;
    41 cur.step = 0;
    42 q[++rear] = cur;
    43
    44 vis[sx][sy] = 1;
    45 while (front != rear)
    46 {
    47 cur = q[++front];
    48 if (maze[cur.x][cur.y] == 'r')
    49 {
    50 isSolve = 1;
    51 break;
    52 }
    53
    54 /**
    55 * 因为没有考虑这个,导致WA了无数次,
    56 * guards的存在可能会破坏广度优先树,因为是
    57 * 它的costTime与可行路‘.’的costTime不同步
    58 *
    59 * 先不改变当前的坐标,干掉guard以后,将x变为可行
    60 * 路径‘.’,在压入队列中,这样可以保持同步
    61 ***/
    62 if (maze[cur.x][cur.y] == 'x')
    63 {
    64 ++cur.step;
    65 vis[cur.x][cur.y] = 1;
    66 maze[cur.x][cur.y] = '.';
    67 q[++rear] = cur;
    68 }
    69 else
    70 {
    71 for (k=0; k<4; ++k)
    72 {
    73 dir.x = cur.x + dx[k];
    74 dir.y = cur.y + dy[k];
    75 dir.step = cur.step + 1;
    76
    77 if (!vis[dir.x][dir.y] && maze[dir.x][dir.y]!='#'
    78 && IsInBound(dir.x, dir.y))
    79 {
    80 vis[dir.x][dir.y] = 1;
    81 q[++rear] = dir;
    82 }
    83 }/* End of For */
    84 }
    85 }/* End of While */
    86 if (isSolve)
    87 {
    88 printf("%d\n", cur.step);
    89 }
    90 else
    91 {
    92 printf("Poor ANGEL has to stay in the prison all his life.\n");
    93 }
    94 }/* BFS */
    95
    96 int main()
    97 {
    98 while (2 == scanf("%d %d", &nNum, &mNum))
    99 {
    100 getchar();
    101 memset(maze, 0, sizeof(maze));
    102 memset(vis, 0, sizeof(vis));
    103
    104 for (i=0; i<nNum; ++i)
    105 {
    106 scanf("%s", maze[i]);
    107 }/* End of For */
    108
    109 /*
    110 * 因为Angel不只有一个Friend
    111 * 可能有多个friends
    112 */
    113 for (i=0; i<nNum; ++i)
    114 {
    115 for (j=0; j<mNum; ++j)
    116 {
    117 if (maze[i][j] == 'a')
    118 { /* 找出Angel的位置,从Angel的位置开始探索 */
    119 sx = i, sy = j;
    120 }
    121 }
    122 }/* End of For */
    123
    124 BFS();
    125 }/* End of While */
    126
    127 return 0;
    128 }


     


    第二种方法是:利用优先队列,按可行点时间的大少,costTime少的优先,即最少值优先,如此一来,guard的访问点就会插入到队列的队尾了

    View Code
      1 #include <queue>
    2 #include <cstdio>
    3 #include <cstdlib>
    4 #include <cstring>
    5 #include <memory.h>
    6 using namespace std;
    7
    8 char maze[210][210];
    9 int vis[210][210];
    10 int i, j, nNum, mNum, sx, sy;
    11 int dx[] = {-1, 1, 0, 0};
    12 int dy[] = {0, 0, -1, 1};
    13
    14 struct Node
    15 {
    16 int x, y, step;
    17
    18 bool operator < (const Node &a) const
    19 {
    20 return step > a.step;
    21 }
    22 };
    23
    24 int IsInBound(int x, int y)
    25 {
    26 if (x<0 || y<0 || x>=nNum || y>=mNum)
    27 {
    28 return 0;
    29 }
    30
    31 return 1;
    32 }/* IsInBound */
    33
    34 void BFS()
    35 {
    36 int k, isSolve = 0;
    37 Node cur, next;
    38 priority_queue<Node> q;
    39
    40 cur.x = sx;
    41 cur.y = sy;
    42 cur.step = 0;
    43 q.push(cur);
    44
    45 vis[sx][sy] = 1;
    46 while (!q.empty())
    47 {
    48 cur = q.top();
    49 q.pop();
    50
    51 if (maze[cur.x][cur.y] == 'r')
    52 {
    53 isSolve = 1;
    54 break;
    55 }
    56
    57 for (k=0; k<4; ++k)
    58 {
    59 next.x = cur.x + dx[k];
    60 next.y = cur.y + dy[k];
    61 next.step = cur.step + 1;
    62
    63 if (IsInBound(next.x, next.y) && !vis[next.x][next.y]
    64 && maze[next.x][next.y]!='#')
    65 {
    66 vis[next.x][next.y] = 1;
    67 if (maze[next.x][next.y] == 'x')
    68 {
    69 ++next.step;
    70 }
    71
    72 q.push(next);
    73 }
    74 }/* End of For */
    75 }/* End of While */
    76 if (isSolve)
    77 {
    78 printf("%d\n", cur.step);
    79 }
    80 else
    81 {
    82 printf("Poor ANGEL has to stay in the prison all his life.\n");
    83 }
    84 }/* BFS */
    85
    86 int main()
    87 {
    88 while (2 == scanf("%d %d", &nNum, &mNum))
    89 {
    90 getchar();
    91 memset(vis, 0, sizeof(vis));
    92 memset(maze, 0, sizeof(maze));
    93
    94 for (i=0; i<nNum; ++i)
    95 {
    96 scanf("%s", maze[i]);
    97 }/* End of For */
    98
    99 for (i=0; i<nNum; ++i)
    100 {
    101 for (j=0; j<mNum; ++j)
    102 {
    103 if (maze[i][j] == 'a')
    104 {
    105 sx = i, sy = j;
    106 }
    107 }
    108 }/* End of For */
    109
    110 BFS();
    111 }/* End of While */
    112
    113 return 0;
    114 }
  • 相关阅读:
    HTTP 的学习
    标量方程求解
    限制器
    差分格式
    Archlinux的基本配置
    布拉休斯方程数值求解
    GNU大型项目构建和覆盖率生成(第一篇)
    plot3d网格读取写入与可视化
    abaqus中的约束
    向量范数和矩阵范数
  • 原文地址:https://www.cnblogs.com/yewei/p/2367796.html
Copyright © 2011-2022 走看看