一个求迷宫路径的算法

最近,实训课上老师布置了若干题目,其中有一个题目是:
提供一个迷宫,用非递归的方法求出一条走出迷宫的路径。
我的想法是:在一个点上,只有上下左右四个方向,只要有规律的探索,就可以找到一条合适的路径了,这里没有要求最佳路径,难度更为低了。
方向的顺序可以自己定,我的顺序就是:从上到下,从左到右。

假定一个点开始,往上走,如果能通过,则把上面的位置的方向定为“上往左”;
以往上面走一步的位置为中心,如果不能往左,就改成“直往上”;
如果不能往上,就改成“上往右”;
如果不能往右,此时,就已经无路可走了,只能回退一步了。
这种情况就如下图所示(图片中的起点在左上角,此时焦点在右上角):
在这里插入图片描述
很奇怪的,为什么为什么要叫“上往左”、“上往右”这么奇怪的名字呢?
实际上,这是有很大影响的。假如只有上下左右四种记录方向,如果全路程没有死路的话,是可以这么用的,但是在遇到死路的时候,往回走的路到底在哪里?这就无法解决了。
这里的“上往左”可能有读者不理解,这里做个说明:前面的“上”代表上一步走的是哪个方向,这样就可以知道当遇到死路时,怎么往回走,后面的“左”代表当前要往哪个方向走。
到什么时候需要回退呢?
如下面图片所示,当都转了一圈的时候,就往回走:
在这里插入图片描述
上面的图片怎么理解?以下为例:
下面有路时,就从“下往左”、“直往下”、“下往右”按顺序搜索,如果能找到路就继续走下去;如果“下往右”时,依然走不了,就回退。
我写了一个简单的过程,代码如下:



#include<stdio.h>

#include<Windows.h>

 

#define N 10

 

int x = 1, y = 1, back
= 0;

 

int image[N][N] = {

    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },

    { 1, 2, 0, 1, 0, 0, 0, 1, 0, 1 },

    { 1, 0, 0, 1, 0, 0, 0, 1, 0, 1 },

    { 1, 0, 0, 0, 0, 1, 1, 0, 0, 1 },

    { 1, 0, 1, 1, 1, 0, 0, 0, 0, 1 },

    { 1, 0, 0, 0, 1, 0, 0, 0, 0, 1 },

    { 1, 0, 1, 0, 0, 0, 1, 0, 0, 1 },

    { 1, 0, 1, 1, 1, 0, 1, 1, 0, 1 },

    { 1, 1, 0, 0, 0, 0, 0, 0, 0, 1 },

    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }

};

 

HANDLE hOutput;

COORD coord = { 0, 0 };

 

void change()

{

 

    //2直往上,3直往下,4直往左,5直往右

    //11左往上,12左往下,13右往上,14右往下,15上往左,16上往右,17下往左,18下往右

 

    //直往上

    if (image[x][y] == 2)

    {

         //如果回退了

         if (back == 1)

         {

             image[x][y] = 16;

             back = 0;

         }

         else

         {

             //如果上面的位置为空

             if (image[x - 1][y] == 0)

             {

                  image[x - 1][y] = 15;

                  x--;

             }

             //如果不为空

             else

             {

                  //改成上往右

                  image[x][y] = 16;

             }

         }

    }

    //直往下

    else if (image[x][y] == 3)

    {

         //如果回退了

         if (back == 1)

         {

             image[x][y] = 18;

             back = 0;

         }

         else

         {

             //如果下面的位置为空

             if (image[x + 1][y] == 0)

             {

                  image[x + 1][y] = 17;

                  x++;

             }

             //如果不为空

             else

             {

                  //改成下往右

                  image[x][y] = 18;

             }

         }

         

    }

    //直往左

    else if (image[x][y] == 4)

    {

         //如果回退了

         if (back == 1)

         {

             image[x][y] = 12;

             back = 0;

         }

         

         else

         {

             //如果左面的位置为空

             if (image[x][y - 1] == 0)

             {

                  image[x][y - 1] = 11;

                  y--;

             }

             //如果不为空

             else

             {

                  //改成左往下

                  image[x][y] = 12;

             }

         }

    }

    //直往右

    else if (image[x][y] == 5)

    {

         //如果回退了

         if (back == 1)

         {

             image[x][y] = 14;

             back = 0;

         }

         else

         {

             //如果右面的位置为空

             if (image[x][y + 1] == 0)

             {

                  image[x][y + 1] = 13;

                  y++;

             }

             //如果不为空

             else

             {

                  //改成右往下

                  image[x][y] = 14;

             }

         }

    }

    //左往上

    else if (image[x][y] == 11)

    {

         //如果回退了

         if (back == 1)

         {

             image[x][y] = 4;

             back = 0;

         }

         else

         {

             //如果上面的位置为空

             if (image[x - 1][y] == 0)

             {

                  image[x - 1][y] = 15;

                  x--;

             }

             //如果不为空

             else

             {

                  //改成往左

                  image[x][y] = 4;

             }

         }

    }

    //左往下

    else if (image[x][y] == 12)

    {

         //如果回退了

         if (back == 1)

         {

             image[x][y] = 0;

             y++;

         }

         else

         {

             //如果下面的位置为空

             if (image[x + 1][y] == 0)

             {

                  image[x + 1][y] = 17;

                  x++;

             }

             //如果不为空

             else

             {

                  back = 1;

                  image[x][y] = 0;

                  y++;

             }

         }

    }

    //右往上

    else if (image[x][y] == 13)

    {

         //如果回退了

         if (back == 1)

         {

             image[x][y] = 5;

             back = 0;

         }

         else

         {

             //如果上面的位置为空

             if (image[x - 1][y] == 0)

             {

                  image[x - 1][y] = 15;

                  x--;

             }

             //如果不为空

             else

             {

                  //改成往右

                  image[x][y] = 5;

             }

         }

         

    }

    //右往下

    else if (image[x][y] == 14)

    {

         //如果回退了

         if (back == 1)

         {

             image[x][y] = 0;

             y--;

         }

         else

         {

             //如果下面的位置为空

             if (image[x + 1][y] == 0)

             {

                  image[x + 1][y] = 17;

                 x++;

             }

             //如果不为空

             else

             {

                  back = 1;

                  image[x][y] = 0;

                  y--;

             }

         }

    }

    //上往左

    else if (image[x][y] == 15)

    {

         //如果回退了

         if (back == 1)

         {

             image[x][y] = 2;

             back = 0;

         }

         else

         {

             //如果左面的位置为空

             if (image[x][y - 1] == 0)

             {

                  image[x][y - 1] = 11;

                  y--;

             }

             //如果不为空

             else

             {

                  //改成往上

                  image[x][y] = 2;

             }

         }

    }

    //上往右

    else if (image[x][y] == 16)

    {

         //如果回退了

         if (back == 1)

         {

             image[x][y] = 0;

             x++;

         }

         else

         {

             //如果右面的位置为空

             if (image[x][y + 1] == 0)

             {

                  image[x][y + 1] = 13;

                  y++;

             }

             //如果不为空

             else

             {

                  back = 1;

                  image[x][y] = 0;

                  x++;

             }

         }

    }

    //下往左

    else if (image[x][y] == 17)

    {

         //如果回退了

         if (back == 1)

         {

             image[x][y] = 3;

             back = 0;

         }

         else

         {

             //如果左面的位置为空

             if (image[x][y - 1] == 0)

             {

                  image[x][y - 1] = 11;

                  y--;

             }

             //如果不为空

             else

             {

                  //改成往下

                  image[x][y] = 3;

             }

         }

    }

    //下往右

    else if (image[x][y] == 18)

    {

         //如果回退了

         if (back == 1)

         {

             image[x][y] = 0;

             x--;

         }

         else

         {

             //如果右面的位置为空

             if (image[x][y + 1] == 0)

             {

                  image[x][y + 1] = 13;

                  y++;

             }

             //如果不为空

             else

             {

                  back = 1;

                  image[x][y] = 0;

                  x--;

             }

         }

    }

}

 

void show()

{

    //以下四行,隐藏光标

    CONSOLE_CURSOR_INFO cci;

    cci.bVisible = 0;

    cci.dwSize = 1;

    SetConsoleCursorInfo(hOutput, &cci);

    //以下两行,防闪屏

    hOutput = GetStdHandle(STD_OUTPUT_HANDLE);

    SetConsoleCursorPosition(hOutput, coord);

    for (int i = 0; i < N; i++)

    {

         for (int j = 0; j < N; j++)

         {

             switch (image[i][j])

             {

             case 0:

                  printf("  ");

                  break;

             case 1:

                  printf("■");

                  break;

             case 2:

             case 11:

             case 13:

                  printf("↑");

                  break;

             case 3:

             case 12:

             case 14:

                  printf("↓");

                  break;

             case 4:

             case 15:

             case 17:

                  printf("←");

                  break;

             case 5:

             case 16:

             case 18:

                  printf("→");

                  break;

             default:

                  printf("出现错误!");

                  break;

             }

         }

         printf("\n");

    }

}

 

int main()

{

    

    for (; !(x == 8 && y == 8);)

    {

         change();

         show();

         Sleep(100);

         system("cls");

    }

    

    return 0;

}


出发点在左上角,终点在右下角,最终路径如下:
在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值