【问题标题】:Finding a path in a maze via backtracking通过回溯在迷宫中寻找路径
【发布时间】:2020-08-22 09:28:04
【问题描述】:

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

#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

【问题讨论】:

  • 你在使用调试器吗?您是否尝试过单步执行您的代码?
  • 我没有使用调试器,但我确实尝试在每个函数中添加 couts 以查看会发生什么,我认为它只是无休止地进行,东西被无休止地打印出来。
  • 请提供输入输出示例。
  • 好的,我将尝试使用带有布尔值的新矩阵忽略我已经访问过的地方,所以我只检查它是 1 还是 0,我将添加输入,但我不知道如何添加换行符stackoverflow cmets xD 第一次使用它。
  • 我检查了你的答案,它有效,非常感谢你节省了我的时间。

标签: c++ iostream


【解决方案1】:

问题是,假设你从(0, 0) -&gt; (1, 0) 出发,然后在(1, 0) 你可以再次回到(0, 0),这将永远循环。为避免这种情况,我创建了一个 visited 数组,如果单元格 (x, y) 已被访问,则其值为 true,否则为 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

【讨论】:

    猜你喜欢
    • 2023-03-26
    • 1970-01-01
    • 2012-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多