迷宫求解

来源:互联网 发布:淘宝宝贝描述尺寸 编辑:程序博客网 时间:2024/06/10 00:07

问题:给指定的入口与出口,求该迷宫的通路。
思想:
1,我们要考虑越界问题。
2,我们要试探下一个位置是否可以通过,若这个位置上下左右都不能通过,则返回上一个位置。再去下一个位置。
代码的实现:

//建立一个存放坐标的结构体struct Pos{    size_t _row;    size_t _col;};template<size_t M, size_t N>class Maze{public:    //初始化迷宫    //Maze(int maze[][N])    Maze(int* maze)    {        for (size_t i = 0; i < M; ++i)        {            for (size_t j = 0; j < N; ++j)            {                //_maze[i][j] = maze[i][j];                _maze[i][j] = maze[i*N+j];            }        }    }    //输出迷宫    void Print()    {        for (size_t i = 0; i < M; ++i)        {            for (size_t j = 0; j < N; ++j)            {                cout<<_maze[i][j]<<" ";            }            cout<<endl;        }        cout<<endl;        if (!shortPath.empty())        {            cout<<"最短路径长度:"<<shortPath.size()<<" 出口";            stack<Pos> tmp = shortPath;            while (!tmp.empty())            {                Pos& top = tmp.top();                printf("[%d,%d]<-", top._row, top._col);                tmp.pop();            }            cout<<"入口"<<endl;        }    }    //查看下一个位置是否越界或合法     bool CheckAccess(Pos next)    {        if (next._row < M && next._col < N            && _maze[next._row][next._col] == 0)        {            return true;        }        return false;    }    //判断下一个位置(非递归)    bool GetPath(Pos entry)    {        Pos cur, next;        cur = entry;        stack<Pos> path;//建立一个栈        path.push(entry);//将入口压入栈中        while (!path.empty())//如果这个栈不为空        {            cur = path.top(); // 取当前的栈顶            _maze[cur._row][cur._col] = 2;//并将当前的位置的内容变为2表示走过的。            if (cur._row == M-1)//如果当前走到最后一行,则找到通路            {                return true;            }            // 上            next = cur;            next._row -= 1;            if (CheckAccess(next))            {                path.push(next);                 continue;            }            // 下            next = cur;            next._row += 1;            if (CheckAccess(next))            {                path.push(next);                continue;            }            // 右            next = cur;            next._col += 1;            if (CheckAccess(next))            {                path.push(next);                continue;            }            // 左            next = cur;            next._col -= 1;            if (CheckAccess(next))            {                path.push(next);                continue;            }            // 回溯            path.pop();//如果上下左右都不通,则返回上一个位置        }        return false;    }  //递归判断下一个位置是否可以走    void GetPathR(Pos entry)    {        _maze[entry._row][entry._col] = 2;//给定入口        if (entry._row == M-1)        {            cout<<"找到一个出口"<<"["<<entry._row<<","<<entry._col<<"]"<<endl;            return;        }        Pos next;        next = entry;        next._row -= 1;        if (CheckAccess(next))        {            GetPathR(next);        }        next = entry;        next._row += 1;        if (CheckAccess(next))        {            GetPathR(next);        }        next = entry;        next._col += 1;        if (CheckAccess(next))        {            GetPathR(next);        }        next = entry;        next._col -= 1;        if (CheckAccess(next))        {            GetPathR(next);        }    }    bool CheckAccess(Pos cur, Pos next)    {        if ((next._row < M && next._col < N)            && (_maze[next._row][next._col] == 0            || _maze[next._row][next._col] > _maze[cur._row][cur._col]))        {            return true;        }        return false;    }    //求最短路径    void GetShortPath(Pos entry, stack<Pos>& path)    {        path.push(entry);//将入口压栈        if (entry._row == M-1)//如果走到了最后一行,则找到了通路        {            if (shortPath.empty() || path.size() < shortPath.size())//如果最短路径为空或者path的路径小于shortPath            {                shortPath = path;//将path路径给shortPath路径            }            cout<<"找到一个出口"<<"["<<entry._row<<","<<entry._col<<"]"<<endl;            path.pop();            return;        }        // 上        Pos next;        next = entry;        next._row -= 1;        if (CheckAccess(entry, next))        {            _maze[next._row][next._col] = _maze[entry._row][entry._col]+1;            GetShortPath(next, path);        }        // 右        next = entry;        next._col += 1;        if (CheckAccess(entry, next))        {            _maze[next._row][next._col] = _maze[entry._row][entry._col]+1;            GetShortPath(next, path);        }        // 下        next = entry;        next._row += 1;        if (CheckAccess(entry, next))        {            _maze[next._row][next._col] = _maze[entry._row][entry._col]+1;            GetShortPath(next, path);        }        next = entry;        next._col -= 1;        if (CheckAccess(entry, next))        {            _maze[next._row][next._col] = _maze[entry._row][entry._col]+1;            GetShortPath(next, path);        }        path.pop();    }protected:    int _maze[M][N];    stack<Pos> shortPath;};//测试代码void TestMaze(){    int mazeArray[10][10] =     {        {1,1,1,1,1,1,1,1,1,1},        {1,1,1,1,1,1,1,1,1,1},        {2,0,0,0,0,0,0,1,1,1},        {1,1,0,1,1,1,0,1,1,1},        {1,1,0,0,0,0,0,1,1,1},        {1,1,1,1,1,0,1,1,1,1},        {1,1,1,1,1,0,1,1,1,1},        {1,1,1,1,1,0,1,1,1,1},        {1,1,1,1,1,0,1,1,1,1},        {1,1,1,1,1,0,1,1,1,1}    };    /*int mazeArray[10][10] =     {        {1,1,1,1,1,1,1,1,1,1},        {1,1,1,1,1,1,1,1,1,1},        {0,0,0,1,1,1,1,1,1,1},        {1,1,0,1,1,1,1,1,1,1},        {1,1,0,0,0,0,1,1,1,1},        {1,1,0,1,1,0,1,1,1,1},        {1,1,0,1,1,0,1,1,1,1},        {1,1,0,1,1,0,1,1,1,1},        {1,1,0,1,1,0,1,1,1,1},        {1,1,0,1,1,0,1,1,1,1}    };*/    Maze<10, 10> maze((int*)mazeArray);    maze.Print();    Pos entry = {2, 0};    stack<Pos> path;    maze.GetShortPath(entry, path);    maze.Print();}