題目確實簡單,思路很容易出來,難點在於障礙的記錄,是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 }