原题链接:
机器人搬重物 - 洛谷https://www.luogu.com.cn/problem/P1126
题目描述
机器人移动学会(RMI
)现在正尝试用机器人搬运物品。机器人的形状是一个直径1.61.6米的球。在试验阶段,机器人被用于在一个储藏室中搬运货物。储藏室是一个 N \times MN×M 的网格,有些格子为不可移动的障碍。机器人的中心总是在格点上,当然,机器人必须在最短的时间内把物品搬运到指定的地方。机器人接受的指令有:向前移动11步(Creep
);向前移动2步(Walk
);向前移动33 步(Run
);向左转(Left
);向右转(Right
)。每个指令所需要的时间为11 秒。请你计算一下机器人完成任务所需的最少时间。
输入格式
第一行为两个正整数N,M(N,M≤50),下面NN行是储藏室的构造,00表示无障碍,11表示有障碍,数字之间用一个空格隔开。接着一行有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
Solution:
我感觉很不错的bfs题,要注意的细节挺多的
1.起点和终点可能重合,所以我这里直接在出队的时候判断是否与终点重合,无须特判
2.标记数组记得带方向(方向类bfs题必备的嘛)
3.如果走一步的时候有障碍,第二步没障碍了,也是不能走的!!一定要停止走!
4.也是最重要的,机器人是占位4格!给的坐标是左上角坐标!所以一定要判断右,下,右下三格格子是否碰到障碍物
这里我先预处理出每个方向左转右转后是哪个方向,并且每个方向往前走坐标该怎么动,然后简单的bfs就okk啦
ACcode:
#include<bits/stdc++.h>
using namespace std;
char lft[129];
char rht[129];
int runx[4][129];
int runy[4][129];
int ma[55][55];
int vis[55][55][127];
int n,m;
int endx,endy;
struct node{
int x,y,step;
char fx;
node(){}
node(int x1,int y1,int step1,char ch):x(x1),y(y1),step(step1),fx(ch){}
};
node beginn;
int main()
{
rht['E'] = 'S',rht['S'] = 'W',rht['W'] = 'N',rht['N'] = 'E';
lft['E'] = 'N',lft['N'] = 'W',lft['W'] = 'S',lft['S'] = 'E';
for(int i = 1;i<=3;++i)
{
runx[i]['E'] = runx[i]['W'] = 0,runx[i]['N'] = -i,runx[i]['S'] = i;
runy[i]['N'] = runy[i]['S'] = 0,runy[i]['E'] = i,runy[i]['W'] = -i;
}
queue<node> q;
cin>>n>>m;
for(int i = 1;i<=n;++i)
for(int j = 1;j<=m;++j)
cin>>ma[i][j];
cin>>beginn.x>>beginn.y>>endx>>endy>>beginn.fx;
beginn.step = 0;
q.push(beginn);
while(!q.empty())
{
int xx = q.front().x;
int yy = q.front().y;
int stepp = q.front().step;
char fx = q.front().fx;
q.pop();
if(vis[xx][yy][fx]) continue;
vis[xx][yy][fx] = 1;
if(xx==endx&&yy==endy){
cout<<stepp<<endl;
return 0;
}
char nfx = lft[fx];
if(!vis[xx][yy][nfx])
q.push(node(xx,yy,stepp+1,nfx));
nfx = rht[fx];
if(!vis[xx][yy][nfx])
q.push(node(xx,yy,stepp+1,nfx));
for(int i = 1;i<=3;++i){
int xxx = xx+runx[i][fx];
int yyy = yy+runy[i][fx];
if(xxx<=0||yyy<=0||xxx>n||yyy>m||ma[xxx][yyy]==1||ma[xxx+1][yyy]==1||ma[xxx][yyy+1]==1||ma[xxx+1][yyy+1]==1) break;
if(xxx+1>n||yyy+1>m) break;
if(vis[xxx][yyy][fx]) continue;
q.push(node(xxx,yyy,stepp+1,fx));
}
}
cout<<-1<<endl;
return 0;
}