迷宫(深度搜索dfs)

来源:互联网 发布:js清空input内容兼容ie 编辑:程序博客网 时间:2024/04/30 09:27

首先输入一个迷宫,用0,1表示,如:m行n列的迷宫

5 4
0 0 1 0
0 0 0 0
0 0 1 0
0 1 0 0
0 0 0 1

0表示通路,1表示障碍。

然后输入起始点的坐标和终止点的坐标,求从起点到终点最少的步数。

用dfs,代码如下:

<span style="font-size:18px;">#include<stdio.h>int book[51][51],p[51][51];int min=99999,endx,endy;//因为终点坐标要在dfs和主函数中使用,所以应该用全局变量int m,n;void dfs(int x,int y,int step){int tx,ty;int next[4][4]={{0,1},{-1,0},{0,-1},{1,0}};//数组代表上下左右四个方向if(x==endx&&y==endy)//当起点和终点相等的时候{if(step<min)//求最小步数min=step;return;//必须要有}for(int k=0;k<=3;k++)//从上下左右四个不同的方向进行搜索{tx=x+next[k][0];ty=y+next[k][1];if(tx<0||tx>=m||ty<0||ty>=n)//超出迷宫边界时,continue{continue;}if(book[tx][ty]==0&&p[tx][ty]==0)//如果当前坐标没有被走过,并且不是障碍{book[tx][ty]=1;//把当前坐标标记为走过dfs(tx,ty,step+1);进行下一阶段的dfsbook[tx][ty]=0;回溯再次搜索时释放已标记的路径}}return;}int main(void){int beginx,beginy;scanf("%d%d",&m,&n);//输入行和列for(int i=0;i<m;i++)for(int j=0;j<n;j++){scanf("%d",&p[i][j]);//输入迷宫,0,1表示}scanf("%d%d%d%d",&beginx,&beginy,&endx,&endy);//输入起点和终点的坐标book[beginx][beginy]=1;//book是标记数组,值为1的时候,代表此坐标已经走过,因为起点已经走过,所以首先置为1dfs(beginx,beginy,0);当前阶段已经做完,并且一步还没有走,所以转向下一个阶段printf("%d\n",min);return 0;}</span>


bfs代码如下:

#include<stdio.h>struct mark{int x;int y;int f;int s;};//因为用到队列,所以定义一个结构体int main(void){int m,n,beginx,beginy,endx,endy,k,tx,ty,head=0,tail=0,flag=0;struct mark queue[2501];//结构体数组int biao[51][51]={0},mi[51][51];标记数组和存迷宫的数组int next[4][4]={{0,1},{1,0},{0,-1},{-1,0}};//方向数组scanf("%d%d",&m,&n);//输入迷宫的行数和列数for(int i=0;i<m;i++)for(int j=0;j<n;j++){scanf("%d",&mi[i][j]);//输入迷宫,0代表通路,1代表障碍}scanf("%d%d%d%d",&beginx,&beginy,&endx,&endy);//输入起点和终点beginx-=1;//转换成数组中的下标,需要减 1beginx-=1;endx-=1;endy-=1;queue[tail].x=beginx;//先把起点入队列queue[tail].y=beginy;queue[tail].f=0;//存放当前节点的父节点(可以不要)queue[tail].s=0;//存放步数biao[beginx][beginy]=1;//把走过的标记为 1 tail++;//队列的尾指针向后移动一位(队列的尾指针始终指向队列最后元素的下一位)/*此时起点已经进入队列中,接下来所要做的就是向下扩展*/while(head<tail)//当head和tail相同时,就表示队列中已经没有元素,就表示扩展完了所有点,但有可能不用遍历完所有点就可以遇到终点{for(k=0;k<4;k++)//从一个点开始,向四个方向扩展{tx=queue[head].x+next[k][0];ty=queue[head].y+next[k][1];if(tx<0||tx>=m||ty<0||ty>=n)//边界判定,必须是在迷宫里面continue;if(mi[tx][ty]==0&&biao[tx][ty]==0)//如果既不是障碍又没有走过,则进入队列{queue[tail].x=tx;queue[tail].y=ty;queue[tail].f=head;queue[tail].s=queue[head].s+1;//步数加1,也就是又进入了新的一层biao[tx][ty]=1;tail++;}if(tx==endx&&ty==endy)//如果遇到终点,退出循环{flag=1;break;}}if(flag==1)//如果遇到终点,直接退出循环,得出结果break;head++;//每次对一个节点扩展完,要转向下一个节点进行扩展}printf("%d\n",queue[tail-1].s);因为下标为tail的没有数据,所以最后一个应该是tail-1return 0;}


0 0
原创粉丝点击