迷宫问题(DFS)

迷宫问题

Description

请解决迷宫问题,并打印出一条从入口到出口的路径。

前进方向:按照下-右-上-左的顺序。

用使用DFS解答该题。

Input

前8行输入一个8*8的int二维数组,其中0表示通路,1表示墙。

第9行输入入口坐标。

第10行输入出口坐标。

Output

输出8*8的int二维数组,其中2表示路径,1表示墙,0表示未经过的点。

Sample Input 1 

0 0 1 0 0 0 1 0
0 0 1 0 0 0 1 0
0 0 0 0 1 1 0 0
0 1 1 1 0 0 0 0 
0 0 0 1 0 0 0 0
0 1 0 0 0 1 0 0 
0 1 1 1 0 1 1 0
1 1 0 0 0 0 0 0
0 0
0 7

Sample Output 1

2 0 1 0 0 0 1 2 
2 0 1 0 0 0 1 2 
2 0 0 0 1 1 0 2 
2 1 1 1 0 0 0 2 
2 2 2 1 0 0 0 2 
0 1 2 2 2 1 0 2 
0 1 1 1 2 1 1 2 
1 1 0 0 2 2 2 2
思路:
  1. 定义迷宫和方向:

    • 使用一个二维数组maze来表示迷宫,其中0表示通路,1表示墙壁,2表示路径。
    • 定义一个方向数组dir,表示在四个方向上的移动:下、右、上、左。
  2. 标记路径:

    • markPath函数用于标记路径,将迷宫中的特定位置标记为2,表示路径。
  3. 判断点的有效性:

    • isValid函数用于判断某个点是否在迷宫内且是通路。
  4. 深度优先搜索(DFS):

    • dfs函数是核心的深度优先搜索算法。从起始点开始,尝试向四个方向之一移动。
    • 对于每个可行的移动,标记当前位置为路径,然后递归调用DFS。
    • 如果找到目标点,返回true,表示路径找到。如果在某个方向上找不到路径,回溯到上一个节点,尝试其他方向。
    • 在回溯时,需要取消当前位置的标记,以便在其他方向上重新尝试。
  5. 主函数:

    • 通过主函数输入迷宫数据,起始点和目标点的坐标。
    • 调用dfs函数解决迷宫问题。
    • 如果找到路径,输出标记过的迷宫,否则输出"No solution found!"。
#include<iostream>
using namespace std;
int maze[8][8];//定义一个8*8的迷宫 用来存放三种情况 0通路 1墙壁 2路径
int direction[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
void markPath(int x,int y)//题目所给的是一个 标记好 0 1 的迷宫,其中0是通路,1是墙壁,而我要做的是通过DFS,将一条通路用2标记出来,也就是做的把0变成2
{
    maze[x][y]=2;
}
bool isValid(int x,int y)//这个函数起到的作用是检查这个点,是否可以被标记为一条通路,需要符合两个条件,在迷宫内,第二个 它是通路
{
if((x>=0)&&(x<8)&&(y>=0)&&(y<8)&&maze[x][y]==0)
    return 1;
else
    return 0;
}
bool dfs(int x,int y,int exitX,int exitY)//深度优先搜索,一共需要两个点的参数,一个是当前位置,一个是最后要退出的点的位置
{
if((x==exitX)&&(y==exitY))//如果递归到了最后的出口,那就先将这最后的通路标记为2,之后退出,此时的遍历的矩阵也已经完成了标记
{
    markPath(x,y);
    return true;
}
for(int i=0;i<4;i++)//这个循环将从四个方向:下 右 上 左展开遍历
{
    int newX=x+direction[i][0];//new 一个点 横坐标是x,纵坐标是y
    int newY=y+direction[i][1];//改变的顺序一次是向 下(1,0)右(0,1)上(-1,0)左(0,—1)
    if(isValid(newX,newY))//检查当前要放置为2的点是否可行
    {
        markPath(x,y);
        if(dfs(newX,newY,exitX,exitY))//如果是一直在通路上 那就会一步步递归进入,直到出口,再通过一次次return true返回回来,最后回到main函数
        {
            return true;
        }
        maze[x][y]=0;//执行这一步是因为下一个点是没法移动到的
    }
}
return false;//这里false有两种情况 一种是遇到墙壁了(isvalid函数不符合)还有一种是上一行maze[x][y]被赋值为0的情况
}
int main()
{
for(int i=0;i<8;i++)//读取迷宫
{
    for(int j=0;j<8;j++)
    {
        cin>>maze[i][j];
    }
}
int entryx,entryy;//读取入口的坐标
int exitX,exitY;//读取出口的坐标
cin>>entryx>>entryy;
cin>>exitX>>exitY;
if(dfs(entryx,entryy,exitX,exitY))
{//符合要求 输出结果
    for(int i=0;i<8;i++)
    {
        for(int j=0;j<8;j++)
        {
            cout<<maze[i][j]<<" ";
        }
        cout<<endl;
    }
}
else
    cout<<"No solution found!"<<endl;
return 0;
}

  • 18
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个Python版的深度优先搜索算法生成迷宫问题的示例代码: ```python import random def generate_maze(rows, cols): # 创建一个 rows 行 cols 列的二维数组,初始化为全 1 maze = [[1] * cols for _ in range(rows)] # 将起点设置为 (0, 0),并将其标记为 0 start_row, start_col = 0, 0 maze[start_row][start_col] = 0 # 使用深度优先搜索算法生成迷宫 dfs(maze, start_row, start_col) return maze def dfs(maze, row, col): # 定义四个方向:上、下、左、右 directions = [(0, -1), (0, 1), (-1, 0), (1, 0)] # 随机打乱方向的顺序 random.shuffle(directions) # 遍历每个方向 for direction in directions: # 计算新的坐标 new_row, new_col = row + direction[0], col + direction[1] # 判断新坐标是否越界或已经被访问过 if (new_row < 0 or new_row >= len(maze) or new_col < 0 or new_col >= len(maze[0]) or maze[new_row][new_col] == 0): continue # 打通当前坐标与新坐标之间的墙壁 if direction == (0, -1): # 左 maze[row][col-1] = 0 elif direction == (0, 1): # 右 maze[row][col+1] = 0 elif direction == (-1, 0): # 上 maze[row-1][col] = 0 elif direction == (1, 0): # 下 maze[row+1][col] = 0 # 递归访问新坐标 dfs(maze, new_row, new_col) # 生成一个 5x5 的迷宫 maze = generate_maze(5, 5) # 打印迷宫 for row in maze: print(row) ``` 这个示例代码可以生成一个指定大小的迷宫,并使用深度优先搜索算法生成迷宫的路径。其中,生成迷宫的主要逻辑在 `generate_maze()` 函数中,它首先创建一个二维数组表示迷宫,然后使用深度优先搜索算法从起点开始访问迷宫中的所有格子,并打通相邻格子之间的墙壁,最终生成迷宫的路径。在这个示例代码中,我们使用随机打乱方向的顺序来增加迷宫的随机性。最后,我们打印生成的迷宫,查看迷宫的路径和墙壁的布局。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值