【BFS】英雄(hero.cpp/pas)

本文介绍了一个迷宫救援问题,英雄Mario需要在限定时间内利用弹簧的弹力避开障碍,找到最优路径救出公主。文章详细解释了如何通过广度优先搜索算法解决此问题,并提供了具体的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

英雄(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.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值