简体   繁体   English

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

[英]Finding a path in a maze via backtracking

I want to make a program to find if a path exists from upper right corner to down left corner in a maze via backtracking.我想编写一个程序,通过回溯查找迷宫中从右上角到左下角的路径是否存在。 The input numbers are n and m which are the dimensions of rectangular maze and a maze, character '.'输入数字是 n 和 m,它们是矩形迷宫和迷宫的维度,字符 '.' means a tile which you can go through and character 'x' means a tile which you cant go through.表示您可以通过 go 的图块,字符“x”表示您无法通过的图块 go。 I have wrote the code, its fairly simple but nothing gets displayed whilst it should display "da" (on Serbian "yes") and "ne" (on Serbian "no").我已经编写了代码,它相当简单但没有显示任何东西,而它应该显示“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;
}

Sample Input:示例输入:

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..

Sample output: da样本 output: da

The problem was that, say if you go from (0, 0) -> (1, 0) , then at (1, 0) you can again go back to (0, 0) and this would loop forever.问题是,如果你 go 从(0, 0) -> (1, 0) ,然后在(1, 0)你可以再次 go 回到(0, 0)并且这将永远循环。 To avoid that, I created a visited array which will have value true if cell (x, y) is already visited, else false .为避免这种情况,我创建了一个visited数组,如果单元格(x, y)已被访问,则该数组的值为true ,否则为false

I have marked where I made the changes with ///////////// change here ///////////// comment我已经用///////////// 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;
}

Here's the link where I tested it: https://ideone.com/vVqAjF这是我测试它的链接: https://ideone.com/vVqAjF

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM