导航

编程题目日志140102:迷宫最简路径

Posted on 2014-01-03 10:17  生存在夹缝中  阅读(240)  评论(0)    收藏  举报

 

题目:

  迷宫的每个点是通道或者墙壁,设计程序生成一个固定迷宫从起点到终点的最简路径(ps:我这是写博客的时候才发现,原来出题那货说的是简单路径,意即不走重复路,我特么看错了……)

 

思路:

  从起点开始,对整个迷宫进行广度优先遍历,找到终点则可保证这的确是最简路径(因为是广度优先,比当前步数更少的步数能走到的位置都已遍历结束)。还是暴力计算的一种形式。有鉴于迷宫这样的东西近似于图,规律是不定的,大概也只能这样了。

 

方案:

  首先确定迷宫矩阵内每个点需要包含的信息:

  typedef struct MazePoint
  {
     int value;//0表示空地,1表示走过,-1表示墙
     int step;//到达这个点的最短步数
     int best_mark;//该点是否在最短路径上 
     int last_ahead;//达成该最短步数的上一点是哪个方向走过来的 0 3 6 9
  }MazePoint;

  其中best_mark和last_ahead用于标记最短路径。

  其次在完成广度优先遍历功能的时候,需要建立队列,将当前点的所有邻接点排入队列中,一直遍历到队列为空。而且,为了区分当前步数(即,需要让计算机知道,当前遍历的点为从起点起第几步能够走到的点),需要建立两个队列,交替排入,交替遍历至空。队列中只需要保留横纵坐标信息即可,其他信息可依照横纵坐标去迷宫点阵内找对应点。队列点结构如下:

  typedef struct Point
  {
     int x,y;//横纵坐标
  }Point;

  在遍历找到了终点之后。利用从终点开始的“last_ahead"信息,找到前一点,将该点的best_mark标记为1,由此向上一直找到起点为止,则将且仅将整条最短路径上的所有点的best_mark设置为1

 

代码:

  只将主程序部分的代码贴下,其他的队列操作、迷宫输入等没啥价值……

  1 void Go(MazePoint **matrix)
  2 {
  3 //思路:利用队列对迷宫进行广度优先搜索,搜索到77则找到了最短路径。 
  4     Queue *head1,*tail1,*head2,*tail2;//两个队列,用以区分是否遍历完当前层 
  5     head1=tail1=head2=tail2=NULL;
  6     
  7     int step=1;//从第1步开始
  8     Point current_point={0,0};//从第00点开始
  9     Point next_point;
 10     matrix[0][0].last_ahead=6;//记初始方向为向下 
 11     QueueIn(&head1,&tail1,current_point);    
 12     while(1)//反正会找到77这个点的 
 13     {
 14         if(step%2==0)//偶数步数,用queue 2;
 15         {
 16             while(head2!=NULL)//遍历所有queue2里的点
 17             { 
 18                 current_point=QueueOut(&head2,&tail2);
 19                 matrix[current_point.x][current_point.y].step=step;
 20                 if(current_point.x+1==7&&current_point.y==7)//哎呀往下够着啦 
 21                 {
 22                     matrix[7][7].last_ahead=6;//最后一步向下 
 23                     matrix[7][7].step=++step;
 24                     break;
 25                 }
 26                 if(current_point.x==7&&current_point.y+1==7)//哎呀往右够着啦 
 27                 {
 28                     matrix[7][7].last_ahead=3;//最后一步向右 
 29                     matrix[7][7].step=++step;
 30                     break;
 31                 }                
 32                 if(current_point.x-1>=0&&matrix[current_point.x-1][current_point.y].step==0&&matrix[current_point.x-1][current_point.y].value!=-1)//当前点可以向上走 
 33                 {
 34                     next_point.x=current_point.x-1;
 35                     next_point.y=current_point.y;
 36                     QueueIn(&head1,&tail1,next_point);//将它上方的这个点排入下一层队列 
 37                     matrix[next_point.x][next_point.y].last_ahead=0;//记方向为向上
 38                 }
 39                 if(current_point.x+1<=7&&matrix[current_point.x+1][current_point.y].step==0&&matrix[current_point.x+1][current_point.y].value!=-1)//当前点可以向下走 
 40                 {
 41                     next_point.x=current_point.x+1;
 42                     next_point.y=current_point.y;
 43                     QueueIn(&head1,&tail1,next_point);//将它下方的这个点排入下一层队列 
 44                     matrix[next_point.x][next_point.y].last_ahead=6;//记方向为向下
 45                 }
 46                 if(current_point.y-1>=0&&matrix[current_point.x][current_point.y-1].step==0&&matrix[current_point.x][current_point.y-1].value!=-1)//当前点可以向左走 
 47                 {
 48                     next_point.x=current_point.x;
 49                     next_point.y=current_point.y-1;
 50                     QueueIn(&head1,&tail1,next_point);//将它左方的这个点排入下一层队列 
 51                     matrix[next_point.x][next_point.y].last_ahead=9;//记方向为向左
 52                 }
 53                 if(current_point.y+1<=7&&matrix[current_point.x][current_point.y+1].step==0&&matrix[current_point.x][current_point.y+1].value!=-1)//当前点可以向右走 
 54                 {
 55                     next_point.x=current_point.x;
 56                     next_point.y=current_point.y+1;
 57                     QueueIn(&head1,&tail1,next_point);//将它右方的这个点排入下一层队列
 58                     matrix[next_point.x][next_point.y].last_ahead=3;//记方向为向右 
 59                 }
 60             }
 61         }
 62         else//奇数层数,用queue1
 63         {
 64             while(head1!=NULL)//遍历所有queue1里的点
 65             { 
 66                 current_point=QueueOut(&head1,&tail1);
 67                 matrix[current_point.x][current_point.y].step=step;
 68                 if(current_point.x+1==7&&current_point.y==7)//哎呀往下够着啦 
 69                 {
 70                     matrix[7][7].last_ahead=6;//最后一步向下 
 71                     matrix[7][7].step=++step;
 72                     break;
 73                 }
 74                 if(current_point.x==7&&current_point.y+1==7)//哎呀往右够着啦 
 75                 {
 76                     matrix[7][7].last_ahead=3;//最后一步向右 
 77                     matrix[7][7].step=++step;
 78                     break;
 79                 }
 80                 if(current_point.x-1>=0&&matrix[current_point.x-1][current_point.y].step==0&&matrix[current_point.x-1][current_point.y].value!=-1)//当前点可以向上走 
 81                 {
 82                     next_point.x=current_point.x-1;
 83                     next_point.y=current_point.y;
 84                     QueueIn(&head2,&tail2,next_point);//将它上方的这个点排入下一层队列
 85                     matrix[next_point.x][next_point.y].last_ahead=0;//记方向为向上
 86                 }
 87                 if(current_point.x+1<=7&&matrix[current_point.x+1][current_point.y].step==0&&matrix[current_point.x+1][current_point.y].value!=-1)//当前点可以向下走 
 88                 {
 89                     next_point.x=current_point.x+1;
 90                     next_point.y=current_point.y;
 91                     QueueIn(&head2,&tail2,next_point);//将它下方的这个点排入下一层队列
 92                     matrix[next_point.x][next_point.y].last_ahead=6;//记方向为向下
 93                 }
 94                 if(current_point.y-1>=0&&matrix[current_point.x][current_point.y-1].step==0&&matrix[current_point.x][current_point.y-1].value!=-1)//当前点可以向左走 
 95                 {
 96                     next_point.x=current_point.x;
 97                     next_point.y=current_point.y-1;
 98                     QueueIn(&head2,&tail2,next_point);//将它左方的这个点排入下一层队列 
 99                     matrix[next_point.x][next_point.y].last_ahead=9;//记方向为向左
100                 }
101                 if(current_point.y+1<=7&&matrix[current_point.x][current_point.y+1].step==0&&matrix[current_point.x][current_point.y+1].value!=-1)//当前点可以向右走 
102                 {
103                     next_point.x=current_point.x;
104                     next_point.y=current_point.y+1;
105                     QueueIn(&head2,&tail2,next_point);//将它右方的这个点排入下一层队列 
106                     matrix[next_point.x][next_point.y].last_ahead=3;//记方向为向右 
107                 }
108             }
109         } 
110         if(matrix[7][7].step!=0)//走到了 
111             break;
112         ++step;
113 //        printf("For test:step=%d\n",step);
114     }
115     
116 //如果正常运行到这里,那么搜索已经成功啦!下一步是按照崔爷的最后一步坑爹要求,
117 //把最佳路径画出来!
118     current_point.x=7;
119     current_point.y=7;//从终点起
120     while(current_point.x!=0||current_point.y!=0)//没走到起点就继续
121     {
122         matrix[current_point.x][current_point.y].best_mark=1;//该点在最佳路径上
123         if(matrix[current_point.x][current_point.y].last_ahead==0)//上一点向上来的 
124             ++current_point.x;
125         else if(matrix[current_point.x][current_point.y].last_ahead==3)//上一点向右来的 
126             --current_point.y;
127         else if(matrix[current_point.x][current_point.y].last_ahead==6)//上一点下来的
128             --current_point.x;
129         else//上一点向左来的
130             ++current_point.y;
131     }
132     matrix[0][0].best_mark=1;//起点当然也在最佳路径上
133 }

这就够长的了……中间的if条件长的令人蛋疼……