依旧是用一个二维数组来存储这个迷宫。最开始的时候小哼在迷宫的(1,1)处,它可以往右走或者往下走。深度优先是一直往右(下)走,直到走不通的时候回到这里。可以使用下面的方法:
通过”一层一层”扩展的方法来找到小哈。扩展的时候发现一个点就将这个点加入到队列中,直到走到小哈的位置(p,q)停下。
用一个结构体实现队列
struct note
{
int x;//横坐标
int y;//纵坐标
int s;//步数
}
struct note que[2501];
int head, tail;
int a[51][51]={0};//用来存储地图
int book[51][51] = {0};//数组book的用处是记录哪些点已经在队列中,防止一个点被重复使用,并全部被初始化0
最先开始的时候需要进行队列的初始化,即将队列设置为空
head = 1;
tail = 1;
第一步将(1,1)加入队列,并且标记(1,1)已经走过
que[tail].x = 1;
que[tail].y = 1;
que[tail].s = 0;
tail++;
book[1][1] = 1;
然后从(1,1)开始,先尝试向右到达了(1,2)
tx = que[head].x;
ty = que[head].y+1;
//判断是否越界
if(tx<1 || tx>n || ty<1 || ty>m)
continue;
//在判断(1,2)是否是障碍物或者已经在路径中
if(a[tx][ty] == 0 && book[tx][ty] == 0)
{
}
若满足上面的条件,则将点入队列,并且标记这个点被使用
//把这个点标记为已经走过
book[tx][ty] = 1;
//插入新的点到队列中
que[tail].x = tx;
que[tail].y = ty;
que[tail].s = que[head].s+1;//步数是父亲步数+1
tail++;
上面是对一个点的操作,我们走完了这个点,还要继续行走。发现(1,1)还是可以到达(2,1),因此要将(2,1)也加入队列,实现代码如上。
将(1,1)扩展完毕后,(1,1)已经没有用了,此时我们将(1,1)出队。出队的操作如下
head++;
接下来我们需要在刚扩展出来的(1,2)和(2,1)这两个点继续向下探索。
(1,1)出队之后,现在队列的head指向(1,2)这个点,现在将这个点继续扩展,通过(1,2)可以到达(2,2)并且将(2,2)也加入队列。重复这个步骤,直到走到了目标位置。
为了向四个方向扩展,与上一节一样需要一个next数组.
int next[4][2] = {
{0, 1},//向右走
{1, 0},//向下走
{0, -1},//向走左
{-1, 0}//向上走
};
全部代码
#include<stdio.h>
struct note
{
int x;//横坐标
int y;//纵坐标
int f;//父亲在队列中的标号
int s;//步数
};
int main()
{
struct note que[2501];
int a[51][51] = {0};
int book[51][51] = {0};
//定义一个表示走方向的数组
int next[4][2] = {{0,1},//向右走
{1,0},//向下走
{0, -1},//向左走
{-1, 0}};//向上走
int head, tail;
int i,j,k,n,m,startx, starty,p,q,tx,ty,flag;
scanf("%d %d", &n, &m);
for(i=1; i<=n; i++)
for(j=1; j<=m;j++)
scanf("%d", &a[i][j]);
scanf("%d %d %d %d", &startx, &starty, &p, &q);
//队列的初始化
head = 1;
tail = 1;
//往队列插入迷宫入口坐标
que[tail].x = startx;
que[tail].y = starty;
que[tail].f = 0;
que[tail].s = 0;
tail++;
book[startx][starty]=1;
flag=0;//用来标记是否到达目标点,0表示暂时没有到达,1表示到达
//当队列不为空的时候循环
while(head<tail)
{
//枚举四个方向
for(k=0; k<=3; k++)
{
//计算下一点的坐标
tx = que[head].x+next[k][0];
ty = que[head].y+next[k][1];
//判断是否越界
for(tx<1 || tx>n || ty<1 || ty>m)
continue;
//判断是否障碍物或者已经在路径中
if(a[tx][ty]==0 && book[tx][ty]==0)
{
//将这个点标记为已经走过
book[tx][ty]=1;
//插入新的点到队列中
que[tail].x=tx;
que[tail].y=ty;
que[tail].f=head;
que[tail].s = que[head].s+1;//步数是父亲的步数加1
tail++;
}
//如果到目标点了,停止扩展,任务结束,退出循环
if(tx==p && ty==q)
{
flag = 1;
break;
}
}
if(flag == 1)
break;
head++;//当一个点扩展完之后,才能对下一个点进行扩展
}
//打印末尾最后一个点
printf("%d",que[tail-1].s);
return 0;
}