ACM/ICPC 之 BFS-简单障碍迷宫问题(POJ2935)

题目确实简单,思路很容易出来,难点在于障碍的记录,是BFS迷宫问题中很经典的题目了。


POJ2935-Basic Wall Maze

  题意:6*6棋盘,有三堵墙,求从给定初始点到给定终点的最短路,输出同一路长的最短路中的任一路径。

  题解:BFS就不说了,对于障碍的记录,我的想法是针对每一个点都记录一次各方向上的情况。比如东边有障碍则在障碍两侧的点增加一个方向数组,用以记录左点的东侧和右点的西侧有障碍,在BFS扩展该方向时,增加一层循环判断一次该方向是否有障碍就行,时间度不会耗费很高,最坏时间度也少于O(4*普通迷宫问题)。

  

  1 //简单障碍迷宫问题
  2 //三堵墙,6*6棋盘,从给定初始点到给定终点的最短路,输出同一最短路中任一路径
  3 //难点在于阻碍的表示-可增加每个点的阻碍方向记录数组
  4 //Memory:168K    Time:0Ms
  5 #include<iostream>
  6 #include<cstring>
  7 #include<cstdio>
  8 using namespace std;
  9 
 10 #define MAX    7
 11 
 12 struct Point {
 13     int size;        //阻碍方向数
 14     int block[3];    //阻碍方向
 15     bool v;        //已访问
 16 }board[MAX][MAX];
 17 
 18 struct State {
 19     int x, y;
 20     int fa;        //记录上一节点
 21     char d;        //记录到下一节点方向
 22 }q[MAX*MAX + 1];
 23 
 24 int sx, sy, ex, ey;
 25 int mov[4][2] = { {0,1}, {1,0}, {0,-1}, {-1,0} };    //东南西北
 26 char d[5] = "ESWN";    //东南西北
 27 
 28 void get_block()
 29 {
 30     int x1, y1, x2, y2;
 31     scanf("%d%d%d%d", &y1, &x1, &y2, &x2);
 32     if (x1 > x2) swap(x1, x2);
 33     if (y1 > y2) swap(y1, y2);
 34     while (y1 == y2 && x1++ < x2)    //竖式障碍
 35     {
 36         board[x1][y1].block[board[x1][y1].size++] = 0;
 37         int tx = x1 + mov[0][0];
 38         int ty = y1 + mov[0][1];
 39         board[tx][ty].block[board[tx][ty].size++] = 2;
 40     }
 41     while(x1 == x2 && y1++ < y2)    //横式障碍
 42     {
 43         board[x1][y1].block[board[x1][y1].size++] = 1;
 44         int tx = x1 + mov[1][0];
 45         int ty = y1 + mov[1][1];
 46         board[tx][ty].block[board[tx][ty].size++] = 3;
 47 
 48     }
 49 }
 50 
 51 //递归输出
 52 void output(State t)
 53 {
 54     if (t.fa){
 55         output(q[t.fa]);
 56         printf("%c", t.d);
 57     }
 58 }
 59 
 60 void bfs()
 61 {
 62     memset(q, 0, sizeof(q));
 63     int front = 1, tail = 2;
 64     q[front].x = sx;
 65     q[front].y = sy;
 66     board[sx][sy].v = true;
 67     while (front < tail)
 68     {
 69         int x = q[front].x;
 70         int y = q[front].y;
 71         for (int i = 0; i < 4; i++)
 72         {
 73             bool flag = true;    //可以朝当前方向前进
 74             for (int j = 0; j < board[x][y].size; j++)
 75             {
 76                 if (i == board[x][y].block[j])
 77                 {
 78                     flag = false; break;
 79                 }
 80             }
 81             
 82             if (flag)    //可以前进
 83             {
 84                 State t;
 85                 t.x = x + mov[i][0];
 86                 t.y = y + mov[i][1];
 87                 t.d = d[i];
 88                 t.fa = front;
 89                 if (t.x == ex && t.y == ey)        //destination
 90                 {
 91                     output(t);
 92                     printf("
");
 93                     return;
 94                 }
 95                 if (t.x > 0 && t.x < MAX && t.y > 0 && t.y < MAX && !board[t.x][t.y].v)
 96                 {
 97                     board[t.x][t.y].v = true;
 98                     q[tail++] = t;
 99                 }
100             }
101         }
102         front++;
103     }
104 }
105 
106 int main()
107 {
108     while (scanf("%d%d", &sy, &sx), sy && sx)
109     {
110         scanf("%d%d", &ey, &ex);
111 
112         memset(board, 0, sizeof(board));
113         for (int i = 0; i < 3; i++)
114             get_block();
115 
116         //if (sx == ex && sy == ey)
117         //    printf("
");
118         //else
119         bfs();
120     }
121 
122     return 0;
123 }