标签: 数据结构算法
题目 A: 5×5 迷宫
输入
输入的数据仅有一组,为一个五行五列的矩阵。矩阵的每一行在一行以空格
为分隔符的输入中表示。
例如,若输入为:
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
,则表示输入为矩阵:
[
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0]
。
该矩阵表示一个 5×5 的迷宫, 0 表示“可行走的路”, 1 则表示“墙壁”,该
迷宫中只可以横向或竖向行走,不能斜向行走。
输出
按顺序在每行以二元组形式输出从迷宫的左上角到右下角的最短路径。 每个
输出的二元组后换行一次。
迷宫的左上角的二元组表示为: (0, 0)。
样例输入
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
样例输出
(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)
#include<stdio.h>
#include<string.h>
int dx[4]={1,-1,0,0}; //dx dy数组是上下左右四个方向
int dy[4]={0,0,1,-1};
int map[5][5]; //存储输入的迷宫
int pre[100]; //存储每个可行节点的前驱层
int visit[5][5]; //将每个可行已走过的节点处标记为1防止回溯
struct str
{
int x;
int y;
}q[3000];//结构型数组模拟队列
void print(int n); //递归输出函数
void bfs() //广度(层次)优先算法
{
int i,j;
int front = 0;
int rear = 1;
int vx,vy;
int a,b;
for(i=0; i<5; i++)//初始化
for(j=0; j<5; j++)
visit[i][j] = 0;
q[0].x = 0;
q[0].y = 0;
pre[0] = -1;
//以上全为初始化
while(front<rear) //当初始化成功或迷宫有通路时(防止死循环迷宫找不到出口)
{
a = q[front].x;
b = q[front].y; //ab是顶节点的坐标(准备向四周扩散的初始方向)
if(a == 4 && b == 4) //当找到出口时(即最后准备扫描的顶节点满足出口条件了 就退出不用再继续四周扫描了)
{
print(front);
return ;
}
//此时顶点四周上下左右节点全扫描一遍,若有满足条件节点全入队,将顶节点对应的front值存到pre数组中下标为顶点对应四周可行节点的位置。
for(i = 0; i < 4; i++)
{
vx = a + dx[i];
vy = b + dy[i];
if(visit[vx][vy]==0 && vx>=0 && vx<5 && vy>=0 &&vy<5 && map[vx][vy]==0)//满足条件入队,并将visit数组对应位置标记为1防止往回走
{
visit[vx][vy] = 1;
q[rear].x=vx;
q[rear].y=vy;
pre[rear]=front;
rear++;
}
}
//一个节点的可行四周的pre值全是front值
front++;//下个顶节点四周的存储front值更新
}
return;
}
void print(int n)
{
int t;
t=pre[n];//最后一个节点
//因为迷宫要从前往后输出路径,所以从最后一个节点(最后一层)开始递归,直到找到第一层,再依次打印。 打印队列中的每层front值对应的x,y坐标。pre存储的是每一层的front域,即每个节点的来源节点。
if(t==0)
{
printf("(0, 0)\n");
printf("(%d, %d)\n",q[n].x,q[n].y);
return ;
}
else
{
print(t);
printf("(%d, %d)\n",q[n].x,q[n].y);
}
}
int main(void)
{
int i,j;
for(i=0; i<5; i++)
for(j=0; j<5; j++)
scanf("%d",&map[i][j]);
bfs();
return 0;
}
补充:迷宫问题的优化
1.随机创建一个迷宫
2.找出最优解
3.输出多条可行路径