首先输入一个迷宫,用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);进行下一阶段的dfs book[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的时候,代表此坐标已经走过,因为起点已经走过,所以首先置为1 dfs(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;//转换成数组中的下标,需要减 1 beginx-=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-1 return 0; }