英雄(hero.cpp/pas)
题目描述(Description):
城堡迷宫由N×M个格子组成,英雄Mario玛丽奥要在城堡迷宫中从起始点移动到目标点去拯救被怪物掳去的公主,他每一步只能从当前所在的格子移动到相邻的4个格子之一,而且不能移出城堡的范围,走一步需要1秒的时间。
城堡中某些格子里面有弹簧,每个弹簧具有特定的能量K,不同弹簧的K值不一定相同。如果Mario跳到一个有弹簧的格子,他就会继续向前跳,直到Mario跳到一个空的格子或者被墙所阻挡无法继续向前。请你计算Mario从起始点到达目标点(公主位置)需要的最短时间,如果不能到达,输出“Impossible”。
输入文件(hero.in):
第一行,两个整数,N和M(3<=N,M<=100),分别表示城堡的行和列。
第二行,一个非负整数K,表示弹簧的数量。接下来K行,每行含3个正整数——X,Y,P。其中X,Y是弹簧的坐标(2<=X<=N-1,2<=Y<=M-1),P是该弹簧的能量。
接下来最后两行,第一行是Mario的坐标,第二行是公主的坐标。
注意:输入文件保证没有一个弹簧是挨着城堡围墙的。
输出文件(hero.out):
输出Mario从初始位置到达公主所在位置需要的最短时间(秒)。
如果不能到达,则输出“Impossible”。(引号不需输出)
样例(Sample):
Sample Input Case 1:
10 10
1
2 7 5
2 8
1 1
Sample Output Case 1:
3
======================
搜索,注意细节
=============================
const
dx:array[1..4]of longint=(1,-1,0,0);
dy:array[1..4]of longint=(0,0,-1,1);
type
node=record
x,y:longint;
end;
var
n,m:longint;
k:longint;
//map:array[1..100,1..100]of longint;
map_t:array[1..100,1..100]of longint;
map_tan:array[1..100,1..100]of longint;
v:array[1..100,1..100]of boolean;
queue:array[1..20000000]of node; //152
// ans:longint;
s_x,s_y,e_x,e_y:longint;
procedure init;
begin
assign(input,'hero.in');
assign(output,'hero.out');
reset(input); rewrite(output);
end;
procedure terminate;
begin
close(input); close(output);
halt;
end;
procedure bfs;
var
i:longint;
l,r:longint;
x1,y1:longint;
x,y:longint;
begin
fillchar(map_t,sizeof(map_t),$7);
l:=0; r:=1;
queue[1].x:=s_x; queue[1].y:=s_y;
map_t[s_x,s_y]:=0;
v[s_x,s_y]:=false;
repeat
inc(l);
if l=20000001 then l:=1;
x:=queue[l].x; y:=queue[l].y;
for i:=1 to 4 do
begin
x1:=queue[l].x; y1:=queue[l].y;
x1:=x1+dx[i]; y1:=y1+dy[i];
if (1<=x1)and(x1<=n)and(1<=y1)and(y1<=m) then
begin
//x:=x1; y:=y1;
while (1<=x1)and(x1<=n)and(1<=y1)and(y1<=m)and(map_tan[x1,y1]<>0) do
begin
// x:=x1; y:=y1;
x1:=x1+dx[i]*map_tan[x1,y1];
y1:=y1+dy[i]*map_tan[x1,y1];
end; //判断弹簧连续跳..
if x1<1 then x1:=1
else if x1>n then x1:=n
else if y1<1 then y1:=1
else if y1>m then y1:=m;
if map_t[x1,y1]>map_t[x,y]+1 then
begin
map_t[x1,y1]:=map_t[x,y]+1;
if v[x1,y1] then
begin
v[x1,y1]:=false;
inc(r);
if r=20000001 then r:=1;
queue[r].x:=x1;
queue[r].y:=y1;
end;
end;
end;
end;
v[queue[l].x,queue[l].y]:=true;
until l>=r;
if map_t[e_x,e_y]<1000000 then writeln(map_t[e_x,e_y])
else writeln('Impossible');
end;
procedure main;
var
i:longint;
x,y,p:longint;
begin
readln(n,m);
readln(k);
fillchar(map_tan,sizeof(map_tan),0);
fillchar(v,sizeof(v),true);
for i:=1 to k do
begin
read(x,y,p);
map_tan[x,y]:=p;
end;
readln(s_x,s_y);
readln(e_x,e_y);
//ans:=maxlongint;
bfs;
end;
begin
init;
main;
terminate;
end.