【洛谷P1126】机器人搬重物

是搜索play的第四弹!

机器人搬重物

题目描述

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

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

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

输入格式

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

输出格式

一个整数,表示机器人完成任务所需的最少时间。如果无法到达,输出 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

解法&&个人感想

这题是少有的一遍过的绿题吧 果然搜索的绿题比较好做?
几个坑点:
1.机器人是有直径的 所以对于一个格子要把周围的四个格点都标记成不能走
2.需要看样例发现左右上下都要缩小一个单位
3.vis代表走到x,y时朝向dir的vis
4.在循环三步时 如果不能走直接break 如果只是走过可以瞬移

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include<bits/stdc++.h>
#define ll long long
using namespace std;
char di;
int n,m,sx,sy,sdir,fx,fy;
int ma[55][55];//ma跑的是格点 注意我们只要将所谓的格子转化成格点就可以
int vis[55][55][5];
struct node{
    int x,y,dir,t;
};
queue<node>q;
int dx[7]={0,-1,0,1,0,0,0},dy[7]={0,0,1,0,-1,0,0};
bool check(int x,int y){
    if(x>=1&&x<=n-1&&y>=1&&y<=m-1&&!ma[x][y]) return true;
    else return false;
}//现在要养成check函数的好习惯
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            scanf("%d",&ma[i][j]);
            if(ma[i][j]==1){
                ma[i-1][j]=1;
                ma[i][j-1]=1;
                ma[i-1][j-1]=1;
            }//打标记
        }
    }
    scanf("%d %d %d %d ",&sx,&sy,&fx,&fy);
    cin>>di;
    if(di=='N') sdir=1;
    if(di=='E') sdir=2;
    if(di=='S') sdir=3;
    if(di=='W') sdir=4;//判断方向
    q.push(node{sx,sy,sdir,0});
    vis[sx][sy][sdir]=1;
    while(!q.empty()){
        int ax=q.front().x,ay=q.front().y,adir=q.front().dir,at=q.front().t;
        q.pop();
        if(ax==fx&&ay==fy){
            printf("%d",at);
            system("pause");
            return 0;
        }
        int tx=ax,ty=ay;
        for(int i=1;i<=3;i++){
            tx+=dx[adir],ty+=dy[adir];
            if(!check(tx,ty)) break;
            if(vis[tx][ty][adir]) continue;
            vis[tx][ty][adir]=1;
            q.push(node{tx,ty,adir,at+1});
        }//循环三步走
        int tdir=adir;
        tdir--;
        if(tdir==0) tdir=4;
        if(check(ax,ay)&&!vis[ax][ay][tdir]){
            vis[ax][ay][tdir]=1;
            q.push(node{ax,ay,tdir,at+1});
        }
        int kdir=adir;
        kdir++;
        if(kdir==5) kdir=1;
        if(check(ax,ay)&&!vis[ax][ay][kdir]){
            vis[ax][ay][kdir]=1;
            q.push(node{ax,ay,kdir,at+1});
        }//转向
    }
    cout<<-1;
    system("pause");
    return 0;
}

  

posted @   青岚之后  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示