题目链接:http://poj.org/problem?id=3984
题目大意:给定一个5*5的迷宫,其中有的点可走,有的点不可走,问从左上角到右下角所需要的最短步数。
并记录下该最短路径的整个过程。
解题思路:bfs搜索
由于这道题需要将路径打印出来,所以用一个结构体描述一点时,不仅需要记录该点的横纵坐标,还需要记录该点的上一个节点的编号。
从队首取出一点,向4个方向开始搜索,如果满足条件,将该点标记为走过,放入队尾,此时还要记录它的上一个点(head-1)。
防止搜索越界。output函数并不打印起点和终点。
代码如下:
1 #include<cstdio> 2 #include<cstring> 3 4 int maze[5][5];//描述迷宫 5 struct Point 6 { 7 int x,y,pre;//描述迷宫中的一点,因为要打印路径,所有需要记录下来该点的上一个节点 8 }; 9 Point Queue[50];//模拟队列实现过程 10 bool vis[5][5];//标记迷宫中的点是否走过 11 12 void output(int i)//该函数不打印起点(0,0)和终点(4,4) 13 { 14 if(Queue[i].pre!=-1)//递归找出每点的上一个点,并输出其坐标 15 { 16 output(Queue[i].pre); 17 printf("(%d, %d)\n",Queue[i].x,Queue[i].y); 18 } 19 } 20 21 void bfs() 22 { 23 memset(vis,0,sizeof(vis));//初始化标记为均未走过 24 25 int head=0,tail=1;//队首,队尾 26 //描述队首 27 Queue[0].x=Queue[0].y=0; 28 Queue[0].pre=-1; 29 vis[0][0]=1; 30 31 while(head<tail) 32 { 33 Point p=Queue[head++];//从队首取出一点,抛弃 34 35 if(p.x==4 && p.y==4) output(p.pre);//若该点是终点,则从它的上一点开始打印,直至终点 36 37 //判断该点是否走过,是否可走,是否处于迷宫中 38 if(p.x+1>=0 && p.x+1<=4 && maze[p.x+1][p.y]==0 && vis[p.x+1][p.y]==0)//向东 39 { 40 vis[p.x+1][p.y]=1;//标记走过 41 Queue[tail].pre=head-1;//因为队首点已经向下移了一格,所以该点的上一点是此时的队首-1 42 Queue[tail].x=p.x+1;//将该点放在队尾 43 Queue[tail++].y=p.y;//将该点放在队尾 44 } 45 if(p.x-1>=0 && p.x-1<=4 && maze[p.x-1][p.y]==0 && vis[p.x-1][p.y]==0)//向西 46 { 47 vis[p.x-1][p.y]=1; 48 Queue[tail].pre=head-1; 49 Queue[tail].x=p.x-1; 50 Queue[tail++].y=p.y; 51 } 52 if(p.y+1>=0 && p.y+1<=4 && maze[p.x][p.y+1]==0 && vis[p.x][p.y+1]==0)//向南 53 { 54 vis[p.x][p.y+1]=1; 55 Queue[tail].pre=head-1; 56 Queue[tail].x=p.x; 57 Queue[tail++].y=p.y+1; 58 } 59 if(p.y-1>=0 && p.y-1<=4 && maze[p.x][p.y-1]==0 && vis[p.x][p.y-1]==0)//向北 60 { 61 vis[p.x][p.y-1]=1; 62 Queue[tail].pre=head-1; 63 Queue[tail].x=p.x; 64 Queue[tail++].y=p.y-1; 65 } 66 } 67 } 68 69 int main() 70 { 71 for(int i=0;i<5;i++)//读入迷宫 72 { 73 for(int j=0;j<5;j++) 74 { 75 scanf("%d",&maze[i][j]); 76 } 77 } 78 printf("(0, 0)\n"); 79 bfs(); 80 printf("(4, 4)\n"); 81 return 0; 82 }
时间: 2024-10-03 16:40:26