自动走迷宫(DFS)

文章提供了三个使用深度优先搜索(DFS)算法解决不同问题的例子。例1是通过DFS寻找从迷宫起点到终点的路径数量,例2利用DFS找到从起点到终点的具体路径,例3则应用DFS找出二维数组表示的区域中最长的下降滑坡路径。所有例子都涉及到边界条件检查和递归调用,并优化了搜索过程以避免重复计算。
摘要由CSDN通过智能技术生成

例1

dfs解决迷宫问题,就是1代表障碍,0代表通过,然后问从头到尾一共有几条路径可以走到终点,这个问题同样是dfs加回溯,就是遍历每一个走过点的上下左右四个方向,直到最后走到终点再重新回溯就是return 1,把走过的还原为0,(因为走过的路都标记为1),最后return sum把顺带可以return的结果输出。

输入两个数n,m,代表迷宫的行和列,接下来输入n行m列由0,1组成的迷宫,其中1代表障碍,求从左上角到右下角的路线个数
#include<stdio.h>
#define N 1000//最大行列数
int mg[N][N];//存放迷宫图
int re[N][N];//记录之前是否走过
int n, m;//行,列
int dfs(int x, int y){//现在在(x,y)点
       if(x< 0 || x > n - 1 || y < 0 || y > m - 1 || re[x][y] == 1 || mg[x][y]== 1) return 0;//走出界外或之前走过或遇到障碍
       if(x ==n - 1 && y == m - 1) return 1;//走到终点
       re[x][y]= 1;//该点标记为走过
       int sum= 0;
       sum +=dfs(x - 1, y);//向左走
       sum +=dfs(x + 1, y);//向右走
       sum +=dfs(x, y - 1);//向上走
       sum +=dfs(x, y + 1);//向下走
       re[x][y]= 0;//该点还原为没有走过
       returnsum;
}
int main(){
       int i,j;
       while(~scanf("%d%d",&n, &m)){//输入行列
              for(i= 0; i < n; i ++)
              {
                     for(j= 0; j < m; j ++) scanf("%d", &mg[i][j]);//读入迷宫图
              }
              printf("%d\n",dfs(0, 0));//输出结果
       }
       return0;
}

例2

大致题意: 第一行输入n,m代表迷宫的行数、列数,接下来输入 n 行和 m 列迷宫(1 表示可以走,0 表示不可以走),倒数第二行代表起始点,倒数第一行代表结束点。用 “→” 连接符表示方向连接
#include <bits/stdc++.h>
using namespace std;
const int N = 30;
int n, m;
int g[N][N], d[N][N];           //g为邻接矩阵存储图,d为记录该点是否已经走过
bool flag = false;
const int dx[4] = {0, -1, 0, 1};
const int dy[4] = {-1, 0, 1, 0};
pair<int, int> start;               //起始点
pair<int, int> over;               //结束点
pair<int, int> after[N][N];            //记录该点往后走哪个点
void dfs(int xx, int yy){
       if(xx== over.first && yy == over.second){
             int a = start.first, b =start.second;
              flag= true;
              
              cout<< "(" << a << "," << b <<")->";
              while(1){
                     autot = after[a][b];
                     a= t.first, b = t.second;
                     if(a== over.first && b == over.second){
                            cout<< "(" << a << "," << b <<")" << endl;
                            break;
                     }
                     elsecout << "(" << a << "," << b<< ")->";
              }
       }
       int x,y;
       for(inti = 0; i < 4; i++){
              x= xx + dx[i], y = yy + dy[i];
              if(x>= 1 && x <= n && y >= 1 && y <= m&&
              d[x][y]== -1 && g[x][y] == 1){
                     d[x][y]= 1;
                     after[xx][yy]= {x, y};          //记录往后走哪个点
                     dfs(x,y);
                     
                     d[x][y]= -1;
                     x= xx, y = yy;
              }
       }
}
int main(){
       cin>> n >> m;
       for(inti = 1; i <= n; i++)
              for(intj = 1; j <= m; j++)
                     cin>> g[i][j];
       cin>> start.first >> start.second;
       cin>> over.first >> over.second;
       
       memset(d,-1, sizeof d);
       d[start.first][start.second]= 1;
       dfs(start.first,start.second);
       if(!flag)cout << -1 << endl;
       return0;
}

例3

Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子

1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9

一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-...-3-2-1更长。事实上,这是最长的一条。

Input
输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。
Output
输出最长区域的长度。
Sample Input
5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
Sample Output
25

AC代码:

#include<iostream>
#include<cstdio>
using namespace std;
int R, C;
int map[105][105];
int mark[105][105] = { 0 };
int dfs(int i, int j)
{
    int k;
    if(mark[i][j]) return mark[i][j];
    if (i !=0 && map[i - 1][j] < map[i][j])
    {
        k =dfs(i - 1, j) + 1;
        if(k> mark[i][j]) mark[i][j] = k;
    }
    if (i !=R - 1 && map[i + 1][j] < map[i][j])
    {
        k =dfs(i + 1, j) + 1;
        if(k>mark[i][j]) mark[i][j] = k;
    }
    if (j !=0 && map[i][j - 1]<map[i][j])
    {
        k =dfs(i, j - 1) + 1;
        if(k>mark[i][j]) mark[i][j] = k;
    }
    if (j !=C - 1 && map[i][j + 1]<map[i][j])
    {
        k =dfs(i, j + 1) + 1;
        if(k>mark[i][j]) mark[i][j] = k;
    }
    returnmark[i][j];
}
 
int main()
{
    int i, j,k, sum = 0;
   scanf("%d%d", &R, &C);
    for (i =0; i < R; i++)
    {
        for(j = 0; j < C; j++)
        {
       scanf("%d", &map[i][j]);
        }
    }
    for (i =0; i < R; i++)
    {
        for(j = 0; j < C; j++)
        {
            k= dfs(i, j);
           if (k>sum) sum = k;
        }
    }
    cout<< sum + 1 << endl;
    return 0;
}

这个题就是把每个数从四个方向都遍历一次,如果满足递减的话就接着dfs,不满足时候把这个数存起来 这个题有几个注意的问题,就是第一个要考虑好边缘临界点,就是四周的点不可以进行某些方向的移动,其次还有一点特别要注意,dfs中的if (mark[i][j]) return mark[i][j];这句话就是为了重复计算,假如从24开始的话已经算出来23,然后如果从25开始,遇到24的话直接可以找到23,而不用在遍历一次,节省了时间。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器人自动走迷宫是一个使用Python编程语言实现的算法问题。下面是一个可能的解答: 首先,我们需要定义迷宫的结构。迷宫可以表示为一个二维的矩阵,其中0表示通道,1表示墙壁,S表示起点,E表示终点。例如,一个迷宫可以表示为以下矩阵: maze = [ [1, 1, 1, 1, 1], [S, 0, 0, 1, 1], [1, 1, 0, 0, 1], [1, 1, 1, 1, E] ] 接下来,我们可以使用深度优先搜索(DFS)或广度优先搜索(BFS)算法来寻找从起点到终点的路径。这里我们选择使用深度优先搜索算法。 首先,我们需要定义一个递归函数,该函数将接受当前位置和当前路径作为参数。在函数内部,我们首先检查当前位置是否在迷宫范围内,如果不在范围内或者当前位置是墙壁,则返回False表示这条路径不可行。 然后,我们检查当前位置是否是终点,如果是终点,则返回True表示找到了一条可行路径。 如果当前位置不是终点,则我们将当前位置标记为已访问,并在上、下、左、右四个方向上递归调用函数,尝试找到一条通往终点的路径。如果其中一条路径返回True,则说明找到了一条可行路径,我们将返回True。 最后,我们在主函数中调用递归函数,传入起点的位置和空列表作为当前路径。如果递归函数返回True,则说明存在一条可行路径,否则说明不存在可行路径。 这是一个简单的机器人自动走迷宫的Python实现。由于篇幅限制,这里只是提供了一个大致的思路,具体的代码实现需要根据实际情况进行编写。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值