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 }
他坐在湖边,望向天空,她坐在对岸,盯着湖面