题目描述
机器人移动学会(RMI)现在正尝试用机器人搬运物品。机器人的形状是一个直径1.6米的球。在试验阶段,机器人被用于在一个储藏室中搬运货物。储藏室是一个N*M的网格,有些格子为不可移动的障碍。机器人的中心总是在格点上,当然,机器人必须在最短的时间内把物品搬运到指定的地方。机器人接受的指令有:向前移动1步(Creep);向前移动2步(Walk);向前移动3步(Run);向左转(Left);向右转(Right)。每个指令所需要的时间为1秒。请你计算一下机器人完成任务所需的最少时间。
输入输出格式
输入格式:
输入的第一行为两个正整数N,M(N,M<=50),下面N行是储藏室的构造,0表示无障碍,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
分析:先把图上的格坐标变为点坐标(一个格变4个点,因为机器人其实就是占了一个点)。然后再暴力搜索。因为如果每次达到的点已经来过,就不管了,减少时间(能跑绝对不走,能走绝对不爬,机器人好可怜)
代码:
const
maxn=300000;
var
fang:array[1..4,1..3,1..2] of longint;
h:array[0..maxn,1..4] of longint;
a:array[0..51,0..51] of longint;
f:array[0..51,0..51,1..4] of boolean;
b:array[0..51,0..51] of boolean;
head,tail,i,j,k,s,n,m,x,y,z,xx,yy,zz,x1,x2,y1,y2:longint;
ch:char;
function pre(sx:longint):longint;
begin
if sx=1 then exit(4) else exit(sx-1);
end;
function next(sx:longint):longint;
begin
if sx=4 then exit(1) else exit(sx+1);
end;
begin
for i:=1 to 3 do
begin
fang[1,i,1]:=-i;
fang[2,i,2]:=-i;
fang[3,i,1]:=i;
fang[4,i,2]:=i;
end;
readln(m,n);
for i:=1 to m do
for j:=1 to n do
read(a[i,j]);
dec(m); dec(n);
for i:=1 to m do
for j:=1 to n do
if (a[i,j]=0) and (a[i+1,j]=0) and (a[i,j+1]=0) and (a[i+1,j+1]=0) then
begin
for k:=1 to 4 do
f[i,j,k]:=true;
b[i,j]:=true;
end;
read(x1,y1,x2,y2);
if (x1=x2) and (y1=y2) then begin writeln(0); halt; end;{这算打点吗}
if not b[x1,y1] or not b[x2,y2] then begin writeln(-1);halt; end;
read(ch);
read(ch);
case ch of
'N':s:=1;
'W':s:=2;
'S':s:=3;
'E':s:=4;
end;
f[x1,y1,s]:=false;
h[1,1]:=x1;
h[1,2]:=y1;
h[1,3]:=s;
head:=0;
tail:=1;
while head<tail do
begin
head:=head mod maxn+1;
x:=h[head,1];
y:=h[head,2];
z:=h[head,3];
zz:=pre(z);
if f[x,y,zz] then
begin
tail:=tail mod maxn+1;
h[tail,1]:=x;
h[tail,2]:=y;
h[tail,3]:=zz;
h[tail,4]:=h[head,4]+1;
f[x,y,zz]:=false;
end;
zz:=next(z);
if f[x,y,zz] then
begin
tail:=tail mod maxn+1;
h[tail,1]:=x;
h[tail,2]:=y;
h[tail,3]:=zz;
h[tail,4]:=h[head,4]+1;
f[x,y,zz]:=false;
end;
for i:=1 to 3 do
begin
xx:=x+fang[z,i,1];
yy:=y+fang[z,i,2];
if f[xx,yy,z] then
begin
tail:=tail mod maxn+1;
h[tail,1]:=xx;
h[tail,2]:=yy;
h[tail,3]:=z;
h[tail,4]:=h[head,4]+1;
f[xx,yy,z]:=false;
if (xx=x2) and (yy=y2) then
begin
writeln(h[tail,4]);
halt;
end;
end else if not b[xx,yy] then break;
end;
end;
writeln(-1);
end.