https://www.luogu.org/problem/P1126
题目描述
机器人移动学会(RMI)现在正尝试用机器人搬运物品。机器人的形状是一个直径1.6的球。在试验阶段,机器人被用于在一个储藏室中搬运货物。储藏室是一个 N×M 的网格,有些格子为不可移动的障碍。机器人的中心总是在格点上,当然,机器人必须在最短的时间内把物品搬运到指定的地方。机器人接受的指令有:向前移动1步(Creep);向前移动2步(Walk);向前移动3 步(Run);向左转(Left);向右转(Right)。每个指令所需要的时间为1 秒。请你计算一下机器人完成任务所需的最少时间。
输入格式
第一行为两个正整数N,M(N,M≤50),下面NNN行是储藏室的构造,0表示无障碍,1表示有障碍,数字之间用一个空格隔开。接着一行有4个整数和1个大写字母,分别为起始点和目标点左上角网格的行与列,起始时的面对方向(东E,南S,西W,北N),数与数,数与字母之间均用一个空格隔开。终点的面向方向是任意的。 输出格式
一个整数,表示机器人完成任务所需的最少时间。如果无法到达,输出−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
代码
#include<algorithm>
#include<iostream>
#include<string.h>
#include<stdio.h>
#include<queue>
#include<set>
using namespace std
;
struct status
{
int x
,y
;
char d
;
bool operator < (const status
&p
) const{
return x
==p
.x
? (y
==p
.y
? d
>p
.d
: y
>p
.y
) : (x
>p
.x
);
}
}temp
;
int n
,m
,tmp
,tx
,ty
;
const int N
=60;
const int M
=60;
bool map
[N
][M
];
char right(char d
){
switch(d
){
case 'N':
return 'E';
case 'E':
return 'S';
case 'S':
return 'W';
case 'W':
return 'N';
}
return 0;
}
char left(char d
){
switch(d
){
case 'N':
return 'W';
case 'W':
return 'S';
case 'S':
return 'E';
case 'E':
return 'N';
}
return 0;
}
void bfs()
{
queue
< pair
<status
, int> > q
;
set
<status
> s
;
q
.push(make_pair(temp
, 0));
while(!q
.empty()){
pair
<status
, int> now
=q
.front();q
.pop();
temp
=now
.first
;
if(temp
.x
==tx
&& temp
.y
==ty
){
printf("%d\n", now
.second
);
return;
}
if(s
.count(temp
))
continue;
else
s
.insert(temp
);
temp
.d
=right(temp
.d
);
if(!s
.count(temp
))
q
.push(make_pair(temp
, now
.second
+1));
temp
=now
.first
;
temp
.d
=left(temp
.d
);
if(!s
.count(temp
))
q
.push(make_pair(temp
, now
.second
+1));
temp
=now
.first
;
switch(temp
.d
){
case 'N':
for(int k
=0; k
<3 && --temp
.x
>0; k
++)
if(!map
[temp
.x
-1][temp
.y
] && !map
[temp
.x
-1][temp
.y
-1]){
if(!s
.count(temp
))
q
.push(make_pair(temp
, now
.second
+1));
}
else
break;
break;
case 'W':
for(int k
=0; k
<3 && --temp
.y
>0; k
++)
if(!map
[temp
.x
-1][temp
.y
-1] && !map
[temp
.x
][temp
.y
-1]){
if(!s
.count(temp
))
q
.push(make_pair(temp
, now
.second
+1));
}
else
break;
break;
case 'E':
for(int k
=0; k
<3 && ++temp
.y
<m
; k
++)
if(!map
[temp
.x
-1][temp
.y
] && !map
[temp
.x
][temp
.y
]){
if (!s
.count(temp
))
q
.push(make_pair(temp
, now
.second
+1));
}
else
break;
break;
case 'S':
for(int k
=0; k
<3 && ++temp
.x
<n
; k
++)
if(!map
[temp
.x
][temp
.y
] && !map
[temp
.x
][temp
.y
-1]){
if (!s
.count(temp
))
q
.push(make_pair(temp
, now
.second
+1));
}
else
break;
break;
}
}
puts("-1");
}
int main(){
scanf("%d %d",&n
,&m
);
for(int k
=0; k
<n
; k
++)
for(int i
=0; i
<m
; i
++)
cin
>>map
[k
][i
];
scanf("%d %d %d %d %c",&temp
.x
,&temp
.y
,&tx
,&ty
,&temp
.d
);
if(map
[temp
.x
][temp
.y
]
|| (temp
.x
>0 ? map
[temp
.x
-1][temp
.y
] : false)
|| (temp
.y
>0 ? map
[temp
.x
][temp
.y
-1] : false)
|| (temp
.x
>0 && temp
.y
>0 ? map
[temp
.x
-1][temp
.y
-1] : false)){
puts("-1");
return 0;
}
bfs();
return 0;
}