1. 程式人生 > >(1)仙島求藥(lake.pas/c/cpp)

(1)仙島求藥(lake.pas/c/cpp)

(1)仙島求藥(lake.pas/c/cpp)

【問題描述】

少年李逍遙的嬸嬸病了,王小虎介紹他去一趟仙靈島,向仙女姐姐要仙丹救嬸嬸。叛逆但孝順的李逍遙闖進了仙靈島,克服了千險萬難來到島的中心,發現仙藥擺在了迷陣的深處。迷陣由M×N個方格組成,有的方格內有可以瞬秒李逍遙的怪物,而有的方格內則是安全。現在李逍遙想盡快找到仙藥,顯然他應避開有怪物的方格,並經過最少的方格,而且那裡會有神祕人物等待著他。現在要求你來幫助他實現這個目標。
下圖 顯示了一個迷陣的樣例及李逍遙找到仙藥的路線.

【輸入】

輸入有多組測試資料. 每組測試資料以兩個非零整數 M 和 N 開始,兩者均不大於20。M 表示迷陣行數, N 表示迷陣列數。接下來有 M 行, 每行包含N個字元,不同字元分別代表不同含義:
1) ‘@’:少年李逍遙所在的位置;
2) ‘.’:可以安全通行的方格;
3) ‘#’:有怪物的方格;
4) ‘*’:仙藥所在位置。
當在一行中讀入的是兩個零時,表示輸入結束。

【輸出】

對於每組測試資料,分別輸出一行,該行包含李逍遙找到仙藥需要穿過的最少的方格數目(計數包括初始位置的方塊)。如果他不可能找到仙藥, 則輸出 -1。

【樣例輸入】

8 8

[email protected]##...#

#....#.#

#.#.##..

..#.###.

#.#...#.

..###.#.

...#.*..

.#...###

6 5

.*.#.

.#...

..##.

.....

.#...

[email protected]

9 6

.#..#.

.#.*.#

.####.

..#...

..#...

..#...

..#...

#[email protected]##

.#..#.

0 0

【樣例輸出】

10

8

-1

【自己題解】

type xy=record
 nx:longint;
 ny:longint;
 nz:longint;
end;
var
 x,y,i,j,ax,ay,h,t,tx,ty:longint;
 a:array[0..21,0..21] of char;
 b:array[0..401] of xy;
 c:array[0..21,0..21] of boolean;
 dx:array[1..4]of longint=(1,0,-1,0);
 dy:array[1..4]of longint=(0,1,0,-1);
procedure bfs;
begin
 h:=1;
 t:=1;
 repeat
  for i:=1 to 4 do
   begin
    tx:=b[h].nx+dx[i];
    ty:=b[h].ny+dy[i];
    if (tx>=1)and(tx<=x)and(ty>=1)and(ty<=y)and(not c[tx,ty]) then
     begin
      inc(t);
      b[t].nx:=tx;
      b[t].ny:=ty;
      b[t].nz:=b[h].nz+1;
      c[tx,ty]:=true;
      if (tx=ax)and(ty=ay) then
       begin
        writeln(b[t].nz);
        exit;
       end;
     end;
   end;
  inc(h);
 until h>t;
 writeln(-1);
end;
procedure pin(s:string);
begin
 assign(input,s+'.in');reset(input);
 assign(output,s+'.out');rewrite(output);
end;
procedure pout;
begin
 close(input);close(output);
end;
begin
 pin('lake');
 readln(x,y);
 while (x<>0)or(y<>0) do
  begin
  fillchar(c,sizeof(c),false);
   for i:=1 to x do
    begin
     for j:=1 to y do
      begin
       read(a[i,j]);
       if (a[i,j]='@') then
        begin
         b[1].nx:=i;
         b[1].ny:=j;
         b[1].nz:=0;
        end;
       if (a[i,j]='*') then
        begin
         ax:=i;
         ay:=j;
        end;
       if (a[i,j]='#') then
        c[i,j]:=true;
      end;
     readln;
    end;
  bfs;
  readln(x,y);
 end;
 pout;
end.