POJ 3984 迷宫问题 --- BFS
/* POJ 3984 迷宫问题 --- BFS */ #include <cstdio> int mapn[5][5]; int x[100], y[100], pre[100]; int front = 0;//队首 int rear = 1;//队尾指向首元素的后一位 int dx[4] = { 1, -1, 0, 0 }; //4个方向 int dy[4] = { 0, 0, 1, -1 }; void printmap(int i){ //注意pre[0]的值为-1,所以(0,0)没有输出 if (pre[i] != -1){ printmap(pre[i]); printf("(%d, %d)\n", x[i], y[i]); } } void bfs(int x0, int y0){ x[front] = x0; y[front] = y0; pre[front] = -1; //首元素(即左上角元素)入队 while (front < rear){ //队不为空时 for (int i = 0; i < 4; ++i){ //往四个方向广搜,判断是否可以访问 int a = x[front] + dx[i]; int b = y[front] + dy[i]; if (a < 0 || a > 4 || b < 0 || b > 4 || mapn[a][b] == 1) continue; //无法访问的点 else{ mapn[a][b] = 1; //第一次访问就是最短的,访问后标记访问过(直接改为1可以省去一个visit数组) //满足的元素入队 x[rear] = a; y[rear] = b; pre[rear] = front; //记录路径(最短路常用) ++rear; if (a == 4 && b == 4) printmap(front); //(4,4)所在的点的下标此时并未入队,故(4,4)也未输出 } }//for(i); ++front; //一访问过的元素出队 } } int main() { for (int i = 0; i < 5; ++i){ for (int j = 0; j < 5; ++j){ scanf("%d", mapn[i] + j); }//for(j) }//for(i) printf("(0, 0)\n"); bfs(0, 0); printf("(4, 4)\n"); return 0; }
用结构体似乎更好理解一点:
#include <cstdio> const int maxn = 5; int mapp[maxn][maxn]; int dx[4] = { -1, 1, 0, 0 }; int dy[4] = { 0, 0, -1, 1 }; struct point{ int x, y, pre; point(int a, int b, int c) :x(a), y(b), pre(c){} point(){} }q[105]; int head, rear; void printmap(int i){ if (i == -1) return; else{ printmap(q[i].pre); printf("(%d, %d)\n", q[i].x, q[i].y); } } void bfs(int x0, int y0){ head = 0, rear = 1; //首元素入队 q[head].x = x0; q[head].y = y0; q[head].pre = -1; while (head < rear){ point tmp = q[head]; for (int i = 0; i < 4; ++i){ int x = tmp.x + dx[i]; int y = tmp.y + dy[i]; if (x < 0 || x >= 5 || y < 0 || y >= 5 || mapp[x][y] == 1) continue; else{ mapp[x][y] = 1; q[rear] = point(x, y, head); ++rear; } if (x == 4 && y == 4) printmap(rear-1); } ++head; } } int main() { for (int i = 0; i < 5; ++i){ for (int j = 0; j < 5; ++j){ scanf("%d", mapp[i] + j); } } bfs(0, 0); return 0; }