• 面试题:寻找迷宫出口


    题目:给出下面迷宫,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         }

    运行结果:

    初始迷宫:

       

    程序找到的路 

  • 相关阅读:
    程序员需要看的书
    linux常见命令实践.
    数据库使用简单总结
    剑指offer【书】之简历抒写
    面试中自己项目和你应该问的问题环节总结
    Matlab近期用到的函数(持续更新)
    排序-快速排序算法
    系统运维-hub, repeater, switch, router初览
    C++基础-位运算
    排序-冒泡排序
  • 原文地址:https://www.cnblogs.com/hehe625/p/7832351.html
Copyright © 2020-2023  润新知