面试题:寻找迷宫出口

题目:给出下面迷宫,0表示通路,1表示障碍物,请找出入口(0,0)至出口(7,7)的路

思路:

1.设置三个指针,last ,now,next 起始位置都设置在入口。

2.实现一个寻找候选点的方法,候选点中不应该包含当前点的位置

3.判断是否有候选点,且是否为出口。

4.如果没有候选点,退回一步,判断是不是入口。

5.如果上一个点不是入口,删除上一个点的第一个候选点,然后试上一个点的第二个候选点

6.如果上一个点没有其他的候选点,再退回一步,从路径中删除这些错误的点

7.重复步骤,直达找到出口

Step 1 :先实现一个Point类:

 1  class Point
 2     {
 3         int x;
 4         int y;
 5         public int Position_X
 6         {
 7             get { return x; }
 8             set { x = value; }
 9         }
10         public int Position_Y
11         {
12             get { return y; }
13             set { y = value; }
14         }
15         public Point() { }
16         public Point(int x, int y)
17         {
18             Position_X = x;
19             Position_Y = y;
20         }
21     }
View Code

Step 2 :定义全局变量,保存可以走的点的List和这些点的可以走的下一个点的List 以及三个指针和是否结束的flag

1         List<Point> way = new List<Point>();
2         List<List<Point>> candicates = new List<List<Point>>();
3         Point sureLast = null;
4         Point sureNow = null;
5         Point notSureNext = null;        
6         bool finish = false;

Step 3 :判断一个点是否是出口

1         public bool IsExit(Point p, int[][] maze)
2         {
3             if (p.Position_X == maze.Length - 1 && p.Position_Y == maze[maze.Length - 1].Length - 1) return true;
4             else return false;
5         }

Step 4:获取候选点,并且把上一步走的点排除在候选点之外

 1      public bool GetNextCandicates(Point p, int[][] maze, ref List<Point> nextp)
 2         {
 3        //如果上下左右的点是边界上的点时,将其设为1,即为不可行
 4             int up = p.Position_X - 1 > 0 ? maze[p.Position_X - 1][p.Position_Y] : 1;
 5             int down = p.Position_X + 1 < maze[p.Position_X].Length ? maze[p.Position_X + 1][p.Position_Y] : 1;
 6             int left = p.Position_Y - 1 > 0 ? maze[p.Position_X][p.Position_Y - 1] : 1;
 7             int right = p.Position_Y + 1 < maze.Length ? maze[p.Position_X][p.Position_Y + 1] : 1;
 8             if (up == 1 && down == 1 && left == 1 && right == 1) return false; //如果上下左右都不可行,返回false没有候选点
 9             else
10             {               
11                 if (right != 1)
12                 {
13                     Point Right = new Point(p.Position_X, p.Position_Y + 1);
14                     if ((sureNow == null)|| (Right.Position_X != sureNow.Position_X || Right.Position_Y != sureNow.Position_Y))
15                     {
16                         nextp.Add(Right);                        
17                     }                   
18                 }
19                 if (down != 1)
20                 {
21                     Point Down = new Point(p.Position_X + 1, p.Position_Y);
22                     if ((sureNow == null) || (Down.Position_X != sureNow.Position_X || Down.Position_Y != sureNow.Position_Y))
23                     {
24                         nextp.Add(Down);                      
25                     }
26                 }
27                 if (left != 1)
28                 {
29                     Point Left = new Point(p.Position_X, p.Position_Y - 1);
30                     if ((sureNow == null) || (Left.Position_X != sureNow.Position_X || Left.Position_Y != sureNow.Position_Y))
31                     {
32                         nextp.Add(Left);                       
33                     }
34                 }
35                 if (up != 1)
36                 {
37                     Point Up = new Point(p.Position_X - 1, p.Position_Y);
38                     if ((sureNow == null) || (Up.Position_X != sureNow.Position_X || Up.Position_Y != sureNow.Position_Y))
39                     {
40                         nextp.Add(Up);                        
41                     }
42                 }
43                 if (nextp.Count > 0) { return true; }
44                 else return false;
45             }
46         }

Step 5 :处理一个错误的点

 1         public bool DealWithWrongPoint (ref Point candicate)
 2         {
 3             bool isBreak = false;
 4             way.Remove(sureNow); //删除保存的路里面的这个点
 5             candicates.Remove(candicates[candicates.Count - 1]); //删除candates里面这个点的候选点                      
 6             candicates[candicates.Count - 1].Remove(sureNow); //将这个点从上一个点的候选点里删掉
 7             sureNow = sureLast;
 8             if (way.Count > 2)
 9             {
10                 sureLast = way[way.Count - 2];
11                 if (candicates[candicates.Count - 1].Count > 0)
12                 {
13                     notSureNext = candicates[candicates.Count - 1][0];
14                     candicate = notSureNext;
15                     return false;
16                 }
17                 else DealWithWrongPoint(ref candicate);
18             }
19             else
20             {
21                 Console.WriteLine("There is no way to exit!");
22                 isBreak = true;
23             }
24             return isBreak;
25         }

Step 6 :寻找通路

 1  public void FindWay(Point candicate, int[][] maze)
 2         {
 3             while (!finish)
 4             {
 5                 List<Point> nextp = new List<Point>();
 6                 if (IsExit(candicate, maze))
 7                 {
 8                     way.Add(candicate);
 9                     Console.WriteLine("Here you find the exit!");
10                     finish = true;
11                     Print(maze);
12                     break;
13                 }
14                 else
15                 {
16                     if (GetNextCandicates(candicate, maze, ref nextp))//如果有候选点
17                     {
18                         if (way.Count == 0)
19                         {
20                             //如果是起点,last和now不动       
21                             sureLast = new Point(0, 0);
22                             sureNow = sureLast;
23                         }
24                         else if (way.Count == 1)
25                         {
26                             //如果是起点的下一个点,last不动
27                             sureNow = candicate;
28                         }
29                         else
30                         {
31                             sureLast = sureNow;
32                             sureNow = candicate;
33                         }
34                         way.Add(candicate);
35                         notSureNext = nextp[0];
36                         candicates.Add(nextp);
37                         //Console.WriteLine("last point is ({0},{1}) , now point is ({2},{3}) , next will try ({4},{5})", sureLast.Position_X, sureLast.Position_Y, sureNow.Position_X, sureNow.Position_Y, notSureNext.Position_X, notSureNext.Position_Y);
38                         FindWay(notSureNext, maze);
39                     }
40                     else //没有候选点
41                     {
42 
43                         if (candicate.Position_X == 0 && candicate.Position_Y == 0)//如果当前点为起点且找不到下一个可行点
44                         {
45                             Console.WriteLine("There is no way to exit!");
46                             break;
47                         }
48                         else
49                         {
50                             candicates[candicates.Count - 1].Remove(candicate);
51                             if (candicates[candicates.Count - 1].Count > 0)//如果sureNow还有候选的下一个点
52                             {
53                                 notSureNext = candicates[way.IndexOf(sureNow)][0];
54                                 FindWay(notSureNext, maze);
55                             }
56                             else //SureNow 没有下一个候选点
57                             {
58                                 if (DealWithWrongPoint(ref candicate))
59                                 {
60                                     break;
61                                 }
62                                 else continue;
63                             }
64                         }
65                     }
66                 }
67             }
68 
69         }

Step 7 :打印迷宫

 1         public void Print(int[][] maze)
 2         {           
 3             for (int i = 0; i <maze.Length; i++)
 4             {
 5                 for (int j = 0; j < maze[maze.Length - 1].Length; j++)
 6                 {
 7                     if (way.Where(a => a.Position_X == i && a.Position_Y == j).ToList().Count > 0)
 8                     {
 9                         Console.Write("");
10                     }
11                     else Console.Write("O");
12                 }
13                 Console.Write("
");
14             }
15         }

主函数,初始化迷宫获取出路

 1         static void Main(string[] args)
 2         {
 3             int[][] maze = new int[8][];
 4             maze[0] = new int[] { 0, 1, 0, 0, 1, 1, 1, 1 };
 5             maze[1] = new int[] { 0, 1, 1, 0, 1, 0, 0, 1 };
 6             maze[2] = new int[] { 0, 0, 0, 0, 1, 0, 1, 1 };
 7             maze[3] = new int[] { 1, 1, 0, 0, 0, 0, 1, 1 };
 8             maze[4] = new int[] { 1, 1, 1, 1, 0, 1, 1, 1 };
 9             maze[5] = new int[] { 1, 0, 1, 0, 0, 0, 0, 1 };
10             maze[6] = new int[] { 1, 0, 0, 0, 1, 1, 0, 1 };
11             maze[7] = new int[] { 1, 1, 1, 0, 1, 1, 0, 0 };
12             Program pg = new Program();
13             pg.FindWay(new Point(0, 0), maze);
14             Console.ReadKey();
15         }

运行结果:

初始迷宫:

   

程序找到的路 

原文地址:https://www.cnblogs.com/hehe625/p/7832351.html