Description
勇敢的德鲁伊法里奥出色的完成了任务之后,正在迅速的向自己的基地撤退。但由于后面有着一大群追兵,所以法里奥要尽快地返回基地,否则就会被敌人捉住。
终于,法里奥来到了最后一站:泰拉希尔原野,穿过这里就可以回到基地了。然而,敌人依然紧追不舍。不过,泰拉希尔的地理条件对法里奥十分有利,众多的湖泊随处分布。敌人需要绕道而行,但法里奥拥有变成鹰的特殊能力,使得他能轻轻松松的飞越湖面。当然,为了保证安全起见,法里奥还是决定找一条能最快回到基地的路。
假设泰拉希尔原野是一个m*n的矩阵,它有两种地形,P表示平地,L表示湖泊,法里奥只能停留在平地上。他目前的位置在左上角(1,1)处,而目的地为右下角的(m,n)。法里奥可以向前后左右四个方向移动或者飞行,每移动一格需要1单位时间。而飞行的时间主要花费在变形上,飞行本身时间消耗很短,所以无论一次飞行多远的距离,都只需要1单位时间。飞行的途中不能变向,并且一次飞行最终必须要降落在平地上。当然,由于受到能量的限制,法里奥不能无限制的飞行,他总共最多可以飞行的距离为D。在知道了以上的信息之后,请你帮助他计算一下,他最快到达基地所需要的时间。
Input
第一行是3个正整数,m(1<=m<=100),n(1<=n<=100),D(1<=D<=100)。表示原野是m*n的矩阵,法里奥最多只能飞行的距离是D。
接下来的m行每行有n个字符,相互之间没有空格。P表示当前位置为平地,L则表示湖泊。 (1,1)和(m,n)一定是平地。
Output
一个整数,表示法里奥到达基地需要的最短时间。如果无法到达基地,则输出impossible。
Sample Input
4 4 2
PLLP
PPLP
PPPP
PLLP
Sample Output
5
这只是一道纯bfs题
枚举向四个方向或飞行
用x,y求出如果进行这次飞行的到达的地方
找到到这个地方所用的飞行距离——r
判断有没有出方阵/到达的地方是否为土地/是否搜过。如果都符合,就入队。
代码如下:
uses math;
const dx:array[1..4]of longint=(0,0,1,-1);
dy:array[1..4]of longint=(1,-1,0,0);
dz:array[1..4]of longint=(2,1,4,3);
var n,m,z,i,j,head,tail,x,y,r:longint;
k:array[0..101,0..101]of longint;
c:char;
state:array[0..1000010,1..2]of longint;
d,time,s:array[0..1000010]of longint;
v:array[0..101,0..101,0..101]of boolean;
begin
readln(n,m,z);
fillchar(v,sizeof(v),false);
for i:=1 to n do
begin
for j:=1 to m do
begin
read(c);
if c='P' then k[i,j]:=1 else k[i,j]:=0;
end;
readln;
end;
state[1,1]:=1;
state[1,2]:=1;
d[1]:=z;
head:=0;
tail:=1;
repeat
inc(head);
for i:=1 to 4 do
for j:=1 to d[head] do
begin
x:=state[head,1]+dx[i]*j;
y:=state[head,2]+dy[i]*j;
if (x<1)or(x>n)or(y<1)or(y>m) then break;
if j<>1 then
r:=max(1,d[head]-j)
else r:=d[head];
if (k[x,y]=0)or(v[x,y,r]=true)or(s[head]=i) then continue;
if (x=n)and(y=m) then
begin
writeln(time[head]+1);
exit;
end;
inc(tail);
state[tail,1]:=x;
state[tail,2]:=y;
s[tail]:=dz[i];
d[tail]:=r;
time[tail]:=time[head]+1;
v[x,y,r]:=true;
end;
until head>=tail;
writeln('impossible');
end.