飘飘乎居士的约会

 
飘飘乎居士的约会 
   

 

 

 

 

背景 Background

 

 

一阵狂风吹过
只听“pong”的一声,飘飘乎居士降落了!!!

 

 

 

 

 

 

 

描述 Description

 

 

又是美妙的一天,这天飘飘乎居士要和MM约会,因此他打扮的格外帅气。但是,因为打扮的时间花了太久,离约会的时间已经所剩无几。
幸运的是,现在飘飘乎居士得到了一张n*m的地图,图中左上角是飘飘乎居士的位置,右下角是约会的地点。‘.’代表马路,‘*’代表房屋。飘飘乎居士只能沿着‘.’行走(也就是不能踏入‘*’),而且行走的方向只能为上下左右的相邻格子。为了不让MM等待太久,飘飘乎居士在整个过程中可能会使用一次飘飘神功(也可能不使用,但最多使用一次),使用飘飘神功后,飘飘乎居士可以走进房屋一次(也就是在全程的行走中最多可以走一个‘*’,注意,只有一个);
  现在飘飘乎居士想要知道最少需要走多少步,飘飘乎居士才能到达约会的地点。

 

 

 

 

 

 

 

输入格式 Input Format

 

 

第一行,2个正整数 n和m,表示一个n*m的矩阵
   接下来n行,每行m个字符,字符一定为 ’.’ 或者是‘*’ ,分别代表马路和房屋。
   输入数据保证左上角和右下角都为‘.’

 

 

 

 

 

 

 

输出格式 Output Format

 

 

一行,如果可以到达,则输入需要行走的最少步数(飘飘神功也记为一步)
      如果不可以到达,则输出‘no’

 

 

 

 

 

 

 

样例输入 Sample Input [复制数据]

 

 

样例输入1
3 3
.*.
...
...

样例输入2
3 3
.**
***
**.

 

 

 

 

 

 

 

样例输出 Sample Output [复制数据]

 

 

样例输入1
4

样例输入2
no

 

 

 

 

 

 

 

注释 Hint

 

 

0<N M <=1000

 

 

 

 

 

 

 

来源 Source

 

 

飘飘乎居士——violet hill

======================================

注意判重...

====================

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;
         bo:boolean;
         step:longint;
       end;
  re=record
       bo:longint;
       n:longint;
     end;
var
  n,m:longint;
  map:array[1..1000,1..1000]of char;
  step:array[1..1000,1..1000]of longint;
  time:array[1..1000,1..1000]of re;
  f:array[0..1001,0..1001]of boolean;
  h:array[1..1000000]of node;
  flag:boolean;
  ans:longint;
procedure init;
begin
  assign(input,'ty1143.in');
  assign(output,'ty1143.out');
  reset(input); rewrite(output);
end;

procedure terminate;
begin
  close(input); close(output);
  halt;
end;

procedure bfs;
var
  i:longint;
  l,r:longint;
  x,y:longint;
begin
  flag:=false;
  ans:=maxlongint;
  
  l:=0; r:=1;
  fillchar(step,sizeof(step),$7);
  h[1].x:=1; h[1].y:=1;
  h[1].step:=0;
  h[1].bo:=true;
  repeat
    inc(l);
    if l=1000000 then l:=1;
    for i:=1 to 4 do
      begin
        x:=h[l].x+dx[i];
        y:=h[l].y+dy[i];
        if f[x,y] then
          begin
            if (map[x,y]='.') then
              begin
                if h[l].bo then
                  begin
                    if time[x,y].n>h[l].step+1 then
                      begin
                        time[x,y].n:=h[l].step+1;
                        inc(r);
                        if r=1000000 then r:=1;
                        h[r].step:=h[l].step+1;
                        h[r].bo:=h[l].bo;
                        h[r].x:=x;
                        h[r].y:=y;
                      end;
                  end;
                if not h[l].bo then
                  begin
                    if time[x,y].bo>h[l].step+1 then
                      begin
                        time[x,y].bo:=h[l].step+1;
                        inc(r);
                        if r=1000000 then r:=1;
                        h[r].step:=h[l].step+1;
                        h[r].bo:=h[l].bo;
                        h[r].x:=x;
                        h[r].y:=y;
                      end;
                  end;
              end
              else
              if (map[x,y]='*')and(h[l].bo)then
              begin
                if time[x,y].bo>h[l].step+1 then
                  begin
                    time[x,y].bo:=h[l].step+1;
                    inc(r);
                    if r=1000000 then r:=1;
                    h[r].step:=h[l].step+1;
                    h[r].bo:=false;
                    h[r].x:=x;
                    h[r].y:=y;
                  end;
              end;
          end;
        if (h[r].x=n) and (h[r].y=m) then
          begin
            if ans>h[r].step then
              begin
                ans:=h[r].step;
                flag:=true;
              end;
          end;
      end;
  until l>=r;
  if flag then writeln(ans)
          else writeln('no');
end;

procedure main;
var
  i,j:longint;
begin
  readln(n,m);
  fillchar(f,sizeof(f),false);
  for i:=1 to n do
    begin
      for j:=1 to m do
        begin
          read(map[i,j]);
          f[i,j]:=true;
          time[i,j].bo:=maxlongint;
          time[i,j].n:=maxlongint;
        end;
      readln;
    end;
  bfs;
end;

begin
  init;
  main;
  terminate;
end.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值