通过回溯在迷宫中寻找路径

时间:2020-08-22 09:28:04

标签: c++ iostream

我想制作一个程序,通过回溯来查找迷宫中从右上角到左下角的路径。输入数字为n和m,它们是矩形迷宫和迷宫的尺寸,字符“。”。表示您可以通过的图块,字符“ x”表示您无法通过的图块。我已经编写了代码,它相当简单,但是什么都没有显示,而应该显示“ da”(在塞尔维亚“是”上)和“ ne”(在塞尔维亚“否”上)。

#include <bits/stdc++.h>

using namespace std;

bool maze[20][20]; //defined maze of maximum size 20x20

//checking if a position is viable for moving through
bool Safe(int n, int m, int x, int y)
{
    if(x >= 0 && x < n && y >= 0 && y < m)
    {
        if(maze[x][y] == 1) return true;
    }
    return false;
}

bool Utility(int n, int m, int x, int y) //main utility function
{
    if(x == n - 1 && y == m - 1 && maze[x][y] == 1) // base case, end of maze
    {
        return true;
    }

    if(Safe(n, m, x, y))
    {
        if(Safe(n, m, x + 1, y)) // checking if it is viable to move down
        {
            if(Utility(n, m, x + 1, y))
            {
                return true;
            }
        }
        if(Safe(n, m, x, y + 1))
        {
            if(Utility(n, m, x, y + 1)) // checking if it is viable to move right
            {
                return true;
            }
        }
        if(Safe(n, m, x - 1, y))
        {
            if(Utility(n, m, x - 1, y)) // checking if it is viable to move up
            {
                return true;
            }
        }
        if(Safe(n, m, x, y - 1))
        {
            if(Utility(n, m, x, y - 1)) // checking if it is viable to move left
            {
                return true;
            }
        }
    }

    return false; // returning false
}

int main()
{
    int n, m;

    cin >> n >> m; // input dimensions of the maze

    for(int i = 0; i < n; i++) // input maze
    {
        for(int j = 0; j < m; j++)
        {
            char c;
            cin >> c;
            if(c == '.') //character '.' means a tile which you can go through
            {
                maze[i][j] = 1;
            }
            else         //character 'x' means a tile which you cannot go through
            {
                maze[i][j] = 0;
            }
        }
    }

    if(Utility(n, m, 0, 0)) //printing yes or no
    {
        cout << "da";
    }
    else
    {
        cout << "ne";
    }
    

    return 0;
}

样本输入:

8 8 
.x.....x 
.x.x.x.x 
.x.x.x.x 
.x.x.x.x 
.x.x.x.x 
.x.x.x.x 
.x.x.x.x 
...x.x..

示例输出:da

1 个答案:

答案 0 :(得分:1)

问题在于,如果您从(0, 0) -> (1, 0)开始,然后在(1, 0),您可以再次回到(0, 0),这将永远循环。为了避免这种情况,我创建了一个visited数组,如果已经访问了单元格true,则其值为(x, y),否则为false

我已经用///////////// change here /////////////评论标记了更改的地方

#include <bits/stdc++.h>

using namespace std;

bool maze[20][20]; //defined maze of maximum size 20x20
///////////// change here /////////////
bool visited[20][20];

bool Safe(int n, int m, int x, int y) //checking if a position is viable for moving through
{
    if(x >= 0 && x < n && y >= 0 && y < m)
    {
        if(maze[x][y] == 1) return true;
    }
    return false;
}

bool Utility(int n, int m, int x, int y) //main utility function
{
    if(x == n - 1 && y == m - 1 && maze[x][y] == 1) // base case, end of maze
    {
        return true;
    }

    ///////////// change here ///////////// 
    if(!visited[x][y] && Safe(n, m, x, y))
    {
        ///////////// change here /////////////
        visited[x][y] = true;

        if(Safe(n, m, x + 1, y)) // checking if it is viable to move down
        {
            if(Utility(n, m, x + 1, y))
            {
                return true;
            }
        }
        if(Safe(n, m, x, y + 1))
        {
            if(Utility(n, m, x, y + 1)) // checking if it is viable to move right
            {
                return true;
            }
        }
        if(Safe(n, m, x - 1, y))
        {
            if(Utility(n, m, x - 1, y)) // checking if it is viable to move up
            {
                return true;
            }
        }
        if(Safe(n, m, x, y - 1))
        {
            if(Utility(n, m, x, y - 1)) // checking if it is viable to move left
            {
                return true;
            }
        }
    }

    return false; // returning false
}

int main()
{
    int n, m;

    cin >> n >> m; // input dimensions of the maze

    for(int i = 0; i < n; i++) // input maze
    {
        for(int j = 0; j < m; j++)
        {
            char c;
            cin >> c;
            if(c == '.') //character '.' means a tile which you can go through
            {
                maze[i][j] = true;
            }
            else         //character 'x' means a tile which you cannot go through
            {
                maze[i][j] = false;
            }
            ///////////// change here /////////////
            visited[i][j] = false;
        }
    }

    if(Utility(n, m, 0, 0)) //printing yes or no
    {
        cout << "da";
    }
    else
    {
        cout << "ne";
    }
    

    return 0;
}

这是我对其进行测试的链接:https://ideone.com/vVqAjF

相关问题