走迷宫

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

 

#include <stdio.h>
#define MAX 100
#define N 7

int 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存放的是前趋到该网格的前进方向。

posted on 2012-12-15 00:23  zm001  阅读(273)  评论(0)    收藏  举报