• Maze迷宫问题(求最优解)


    迷宫地形我们可以通过读文件的形式,通过已知入口逐个遍历坐标寻找通路。

    文件如图:

    wKiom1cSCnTB8pO4AAAZiAM5LuE146.png

    每个坐标的位置用结构体来记录:

    struct Pos    //位置坐标
    {
       int  _row;
       int _col;
    };
    

     定义行列范围:

    #define M 10   //行
    #define N 10   //列
    

    初始化迷宫数组
    将通过读文件的方式获取的字符转成整型数据,保存在M行N列的数组中。

    void InitMaze(int* maze)
    {  
        struct WavHeadhWAV;
        FILE* fout = fopen("MazeMap.txt", "r");   // .txt文件要放在当前目录下
        if (fout == NULL)                       // 这里一定要检查读文件是否成功
        {
            cout << "can't find MazeMap.txt !" << endl<<endl;
            return;
        }
        for (int i = 0; i < M; i++)
        {
            for (int j = 0; j < N;)
            {
                char ch = fgetc(fout);
                if (ch=='1'||ch=='0')
                {
                    maze[i*N + j] = ch - '0';
                    j++;
                }
            }
        }
        fclose(fout);
    }
    

    回溯查找通路

    利用栈来存储通路,通过上下左右四个方向依次遍历,如果该位置满足条件,就将它入栈,并将该位置的数据置为2;如果四个方向都不满足条件就执行出栈操作,回溯查找满足条件的位置(这时候如果栈为空了,说明查找通路失败),继续循环遍历,直到找到出口为止。

    这里建立一个最小栈,如果找到出路,就将该栈赋给最小栈,并将出口置为1,继续回溯查找通路,如果又一次找到通路,就将该栈的长度与最小栈进行比较,如果该栈长度比最小栈还要小,就将它再一次赋给最小栈(保证最小栈是最短的通路),继续回溯,直到整个栈为空,回到了入口,程序结束。

    bool SearchMazePath(int *maze, Pos entry, stack<Pos>& paths)   // 利用栈回溯查找通路,并实现迷宫的最优解
    {
        assert(maze);
        stack<Pos>min;
        paths.push(entry);
        while (!paths.empty())
        {
            Pos cur = paths.top();
            maze[cur._row*N+cur._col] = 2;
            if (cur._row==M-1)
            {
                if (paths.size()< min.size() || min.size() == 0)
                {
                    min = paths;
                }
                paths.pop();
                maze[min.top()._row*N + min.top()._col] = 1;
            }  
            Pos next = cur;
            next._col--;  //左
            if (CheckIsAccess(maze, next))
            {
                paths.push(next);
                maze[next._row*N + next._col] = 2;
                continue;
            }
            next = cur;
            next._col++; //右
            if (CheckIsAccess(maze, next))
            {
                paths.push(next);
                maze[next._row*N + next._col] = 2;
                continue;
            }
            next = cur;
            next._row--; //上
            if (CheckIsAccess(maze, next))
            {
                paths.push(next);
                maze[next._row*N + next._col] = 2;
                continue;
            }
            next = cur;
            next._row++; //下
            if (CheckIsAccess(maze, next))
            {
                paths.push(next);
                maze[next._row*N + next._col] = 2;
                continue;
            }
            paths.pop();
        }
        if (paths.empty()&&!min.empty())
        {
                maze[min.top()._row*N + min.top()._col] = 2;
                return true;
        }
        return false;
    }
    

      检查该位置是否合法:(坐标在行列范围之内)

    bool CheckIsAccess(int* maze, const Pos& next)    // 检查该位置是否合法
    {
        assert(maze);
        if ((next._row >= 0 && next._row <= N) && (next._col >= 0 && next._col < M) && maze[next._row*N + next._col] == 0)
        {
            return true;
        }
        return false;
    }
    

      打印迷宫:

    void PrintMaze(int *maze)   // 打印迷宫
    {
        assert(maze);
        for (int i = 0; i < M; i++)
        { 
            for (int j = 0; j < N; j++)
            {
                cout << maze[i*N + j] <<" " ;
            }
            cout << endl;
        }
        cout << endl;  
    }
    

      

  • 相关阅读:
    C# BackGroundWorker控件演示代码
    C#多线程池演示例程下载图片
    反流技术之IE插件技术研究第二部分
    C# 从剪贴板中读取HTML中的中文字符出现乱码问题的解决方案
    C#单线程演示程序带参数
    C# 中as和is的用法总结
    Delphi关于记录文件的操作
    用PowerDesigner创建Access数据库
    常用Delphi开发资料网址
    等待外部应用程序的执行结果
  • 原文地址:https://www.cnblogs.com/Lynn-Zhang/p/5404843.html
Copyright © 2020-2023  润新知