走迷宫

来源:互联网 发布:药物靶点数据库 编辑:程序博客网 时间:2024/05/01 19:00

一个网格迷宫又n行m列的单元格组成,每个单元格要么是空地(用0来表示),要么是障碍物(用1来表示)。你的任务是找到一条从起点到终点的最短移动序列。起点和终点保证是空地。n, m<=100 。为了简单我的程序直接给出迷宫图,且大小为 7*7。

 

#include <stdio.h>#define MAX 100#define N 7int maze[N][N] = {//1代表障碍物{0,0,0,1,0,0,0},{0,0,1,0,0,0,0},{0,0,1,0,1,1,0},{0,0,1,0,0,0,0},{0,0,0,0,1,0,0},{0,0,1,0,0,0,0},{0,0,0,0,0,0,0}};int vis[N][N], fa[N][N], last_dir[N][N];int dx[4] = {-1, 0, 1, 0};int dy[4] = {0, 1, 0, -1};int q[MAX];int dir[MAX];char name[4] = {'U','R','D','L'};void bfs(int x, int y){int u = x * N + y;int front = 0, rear = 0;int nx, ny, d, v;q[rear++] = u;fa[x][y] = u;vis[x][y] = 1;//千万别忘记了标记此处的访问记录while (rear > front){u = q[front++];x = u / N;y = u % N;for (d=0; d<4; d++){//代表四个方向nx = x + dx[d];ny = y + dy[d];if (nx>=0 && nx<N && ny>=0 && ny<N && !maze[nx][ny] && !vis[nx][ny]){//(nx, ny)没有出界,不是障碍且没被访问过v = nx * N + ny;q[rear++] = v;fa[nx][ny] = u;//记录(nx, ny)的前趋vis[nx][ny] = 1;//访问记录last_dir[nx][ny] = d;//记录从(x, y)到(nx, ny)的方向}}}}/*递归实现路径输出void print_path(int x, int y){int fx = fa[x][y] / N;int fy = fa[x][y] % N;if (fx != x || fy != y){print_path(fx, fy);putchar(name[last_dir[x][y]]);}}*///显式栈实现路径输出void print_path(int x, int y){int c = 0;for (;;){int fx = fa[x][y] / 7;int fy = fa[x][y] % 7;if (fx == x && fy == y)break;dir[c++] = last_dir[x][y];x = fx;y = fy;}while (c--){putchar(name[dir[c]]);}}int main(void){int i, j;for (i=0; i<N; i++){for (j=0; j<N; j++)printf("%d", maze[i][j]);printf("\n");}printf("从入口到出口迷宫路径:\n");bfs(0, 0);//广搜((0, 0)迷宫入口)print_path(0, 6);//打印行走方向((0, 6)为迷宫出口)printf("\n");return 0;}


 

看刘汝佳的代码基本上不用注释,一遍遍的看下去就会有收获,看的越多越觉得妙不可言。

走迷宫就是把一个用三个图(数组)存放一个图(迷宫)的信息,其中vis是标记该网格是否访问过,避免重复访问造成死循环,fa是记录该网格的前趋,last_dir存放的是前趋到该网格的前进方向。