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;
}