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("\n");
 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("\n");
118         //else
119         bfs();
120     }
121 
122     return 0;
123 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM