DFS——机器人搬重物

机器人搬重物

题目描述

机器人移动学会(RMI)现在正尝试用机器人搬运物品。机器人的形状是一个直径 1.6 1.6 1.6 米的球。在试验阶段,机器人被用于在一个储藏室中搬运货物。储藏室是一个 N × M N\times M N×M 的网格,有些格子为不可移动的障碍。机器人的中心总是在格点上,当然,机器人必须在最短的时间内把物品搬运到指定的地方。机器人接受的指令有:

  • 向前移动 1 1 1 步(Creep);
  • 向前移动 2 2 2 步(Walk);
  • 向前移动 3 3 3 步(Run);
  • 向左转(Left);
  • 向右转(Right)。

每个指令所需要的时间为 1 1 1 秒。请你计算一下机器人完成任务所需的最少时间。

输入格式

第一行为两个正整数 N , M   ( 1 ≤ N , M ≤ 50 ) N,M\ (1\le N,M\le50) N,M (1N,M50),下面 N N N 行是储藏室的构造, 0 0 0 表示无障碍, 1 1 1 表示有障碍,数字之间用一个空格隔开。接着一行有 4 4 4 个整数和 1 1 1 个大写字母,分别为起始点和目标点左上角网格的行与列,起始时的面对方向(东 E \tt E E,南 S \tt S S,西 W \tt W W,北 N \tt N N),数与数,数与字母之间均用一个空格隔开。终点的面向方向是任意的。

输出格式

一个整数,表示机器人完成任务所需的最少时间。如果无法到达,输出 − 1 -1 1

样例 #1

样例输入 #1

9 10
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 1 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 1 0
7 2 2 7 S

样例输出 #1

12

思路+细节

本道题我们我们看数据范围,不怎么大,因此我们用dfs(其实后面觉得bfs更好更优,但是我懒,不想写bfs),但单纯的dfs,可能会爆栈,因此我们想到记忆化搜索,我们用,f[i][j][k]来表示在坐标某点且此时微米某个方向的步数集合,如果当我们的步数比这个记忆化的来的大,我们就不用继续搜索了。为什么呢?因为你都比他大了,那后边搜索的就不是最优的了,就没有搜索的必要了。特别注意,如果是记忆化搜索,那就不需要st数组了。

本道题有很多细节。

  • 细节1:机器人有体积,因此不能在x=0或者n,y=m或者0上。
  • 细节2:图中已经给了我们方向了(x向下,向右),因此这个地方要写对应,就比如方向为N,此时是y不变,x变化(这个地方搞错卡了好久)。
  • 细节3:题目给定3种速度,分别为1,2,3,特别注意就是,你可以走3,2,步的前提就是在这3,2步的直线上(也就是走过的直线)不能有黑点。
  • 细节4:题目测试用例给的图是框框图,而不是点图。因此题目给的0应该它的四周都是1(很明显,你自己对应一下题目给你的图),这点很重要,空格图转化为点图。

代码

#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;

const int N = 60;

int w[N][N];
bool st[N][N];
int n,m;
int stx,sty,edx,edy;
char op1;
int ans=0x3f3f3f3f;
int f[N][N][5];//已经搜到的步数
//记忆化应该适用于有明确每个阶段采用
char op[]={'N','E','S','W'};

int change(char s){
    if(s=='N'){
        return 0;
    }else if(s=='E'){
        return 1;
    }else if(s=='S'){
        return 2;
    }else{
        return 3;
    }
}

void dfs(int x,int y,int step,char s){
    
    if(x==edx&&y==edy){
        ans=min(ans,step);
        return;
    }
    
    
    if(step>=f[x][y][change(s)])return;
    
    f[x][y][change(s)]=step;
    
    //五个方式轮流
    dfs(x,y,step+1,op[((change(s)-1)%4+4)%4]);//左转
    dfs(x,y,step+1,op[((change(s)+1)%4+4)%4]);
    
    if(s=='N'){
        if(x-3>0&&w[x-3][y]==0&&w[x-2][y]==0&&w[x-1][y]==0)dfs(x-3,y,step+1,s);
        if(x-2>0&&w[x-2][y]==0&&w[x-1][y]==0)dfs(x-2,y,step+1,s);
        if(x-1>0&&w[x-1][y]==0)dfs(x-1,y,step+1,s);
    }else if(s=='E'){
        if(y+3<m&&w[x][y+1]==0&&w[x][y+2]==0&&w[x][y+3]==0)dfs(x,y+3,step+1,s);
        if(y+2<m&&w[x][y+2]==0&&w[x][y+1]==0)dfs(x,y+2,step+1,s);
        if(y+1<m&&w[x][y+1]==0)dfs(x,y+1,step+1,s);
    }else if(s=='S'){
        if(x+3<n&&w[x+1][y]==0&&w[x+2][y]==0&&w[x+3][y]==0)dfs(x+3,y,step+1,s); 
    	if(x+2<n&&w[x+1][y]==0&&w[x+2][y]==0)dfs(x+2,y,step+1,s);    	
    	if(x+1<n&&w[x+1][y]==0)dfs(x+1,y,step+1,s);   
    }else{
        if(y-3>0&&w[x][y-1]==0&&w[x][y-2]==0&&w[x][y-3]==0)dfs(x,y-3,step+1,s); 
        if(y-2>0&&w[x][y-1]==0&&w[x][y-2]==0)dfs(x,y-2,step+1,s);    
    	if(y-1>0&&w[x][y-1]==0) dfs(x,y-1,step+1,s);
    }
}

int main(){
    cin>>n>>m;
    
    memset(f,0x3f,sizeof f);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            int x;
            cin>>x;
            if(x==1){
                w[i][j]=w[i-1][j-1]=w[i-1][j]=w[i][j-1]=1;
            }
        }
    }
    
    cin>>stx>>sty>>edx>>edy>>op1;
    
    dfs(stx,sty,0,op1);
    
    if(ans==0x3f3f3f3f)ans=-1;
    
    cout<<ans;
    
    return 0;
}
  • 20
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是使用深度优先搜索(DFS)实现机器人寻路程序的示例代码: ```python # 定义迷宫地图和机器人起点 maze = [ [0, 0, 0, 0, 0], [0, 1, 1, 0, 0], [0, 0, 1, 0, 0], [0, 1, 1, 1, 0], [0, 0, 0, 0, 0] ] start = (1, 1) # 定义 DFS 函数 def dfs(maze, start, visited): if start in visited: return False if maze[start[0]][start[1]] == 1: return False if maze[start[0]][start[1]] == 2: print("找到终点:", start) return True visited.append(start) directions = [(0, 1), (0, -1), (1, 0), (-1, 0)] for d in directions: next_pos = (start[0] + d[0], start[1] + d[1]) if dfs(maze, next_pos, visited): return True return False # 调用 DFS 函数 dfs(maze, start, []) ``` 在上述代码中,我们首先定义了一个迷宫地图和机器人的起点。然后,我们定义了一个 `dfs` 函数来实现 DFS 算法。该函数接收三个参数:迷宫地图、机器人起点和已访问过的位置列表。在每个位置,我们检查该位置是否已被访问过、是否为墙壁或终点。如果是终点,我们就输出该位置并返回 True。否则,我们将该位置添加到已访问过的位置列表中,并继续遍历该位置的上下左右四个方向。如果没有找到终点,我们就返回 False。 最后,我们调用 `dfs` 函数,并将已访问过的位置列表初始化为空列表 `[]`。如果机器人能够找到终点, `dfs` 函数将返回 True,否则返回 False。在本例中,机器人能够从起点 (1, 1) 找到终点 (3, 3)。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

green qwq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值