Description
有一副n*m的地图,有n*m块地,每块是下列四种中的一种:
墙:用#表示,墙有4个面,分别是前面,后面,左面,右面。
起点:用C表示,为主角的起点,是一片空地。
终点:用F表示,为主角的目的地,是一片空地。
空地:用 . 表示。
其中除了墙不能穿过,其他地方都能走。
主角有以下3种操作:
1.移动到相邻的前后左右的地方,花费一个单位时间。
2.向前后左右其中一个方向发射子弹,子弹沿直线穿过,打在最近的一堵墙的一面,然后墙的这面就会形成一个开口通往秘密通道。同一时间最多只能有两个开口,若出现有3个开口,出现时间最早的开口会立即消失。该操作不用时间。
3.可以从一个与开口相邻的空地跳进去,进入秘密通道,从另外一个开口正对的空地跳出来。这个过程花费一个单位时间。
地图四周都是墙,问主角最少用多少时间从C走到F。C和F只会出现一次。
墙:用#表示,墙有4个面,分别是前面,后面,左面,右面。
起点:用C表示,为主角的起点,是一片空地。
终点:用F表示,为主角的目的地,是一片空地。
空地:用 . 表示。
其中除了墙不能穿过,其他地方都能走。
主角有以下3种操作:
1.移动到相邻的前后左右的地方,花费一个单位时间。
2.向前后左右其中一个方向发射子弹,子弹沿直线穿过,打在最近的一堵墙的一面,然后墙的这面就会形成一个开口通往秘密通道。同一时间最多只能有两个开口,若出现有3个开口,出现时间最早的开口会立即消失。该操作不用时间。
3.可以从一个与开口相邻的空地跳进去,进入秘密通道,从另外一个开口正对的空地跳出来。这个过程花费一个单位时间。
地图四周都是墙,问主角最少用多少时间从C走到F。C和F只会出现一次。
Input
第一行输入两个正整数n,m。
接下来n行,每行m个字符描述地图。
接下来n行,每行m个字符描述地图。
Output
输出1个整数,表示最短时间完成路途。如果无解输出nemoguce
Solutions
这道题目可以用最短路来做。
我们首先可以预处理出每一个格子向上下左右第一堵 墙在哪。
这个时间复杂度是 O(n^2)的。
两种连边。
第一种就是每一个格子向他周围四个方向连一条长度 为 1 的边。
第二种就是每一个格子向他上下左右的第一堵墙连一 条长度为格子与最近的墙距离的边。
从 C 到 F 求一遍最短路即可。 假如不存在路径,就输出 nemoguce。
代码
1 type 2 arr=record 3 x,y,w,next:longint; 4 end; 5 var 6 n,m,nm,qq,zz,ll:longint; 7 b:array [0..501,0..501] of longint; 8 st:array [0..501,0..501] of char; 9 a:array [0..5000001] of arr; 10 ls,d,v,list:array [0..1000001] of longint; 11 function min(o,p:longint):longint; 12 begin 13 if o<p then exit(o); 14 exit(p); 15 end; 16 17 procedure add(x,y,z:longint); 18 begin 19 inc(nm); 20 a[nm].x:=x; a[nm].y:=y; a[nm].w:=z; 21 a[nm].next:=ls[x]; ls[x]:=nm; 22 end; 23 24 procedure init; 25 var 26 i,j,k,mi:longint; 27 x1,x2,x3,x4,y1,y2,y3,y4:longint; 28 begin 29 readln(n,m); 30 nm:=0; ll:=0; 31 for i:=1 to n do 32 begin 33 for j:=1 to m do 34 begin 35 read(st[i,j]); 36 if st[i,j]<>'#' then 37 begin 38 inc(ll); 39 b[i,j]:=ll; 40 if st[i,j]='C' then qq:=ll; 41 if st[i,j]='F' then zz:=ll; 42 end; 43 end; 44 readln; 45 end; 46 for i:=1 to n do 47 for j:=1 to m do 48 if st[i,j]<>'#' then 49 begin 50 if st[i-1,j]<>'#' then add(b[i,j],b[i-1,j],1); 51 if st[i+1,j]<>'#' then add(b[i,j],b[i+1,j],1); 52 if st[i,j-1]<>'#' then add(b[i,j],b[i,j-1],1); 53 if st[i,j+1]<>'#' then add(b[i,j],b[i,j+1],1); 54 x1:=i; x2:=i; x3:=i; x4:=i; 55 y1:=j; y2:=j; y3:=j; y4:=j; 56 while st[x1-1,y1]<>'#' do dec(x1); 57 while st[x2+1,y2]<>'#' do inc(x2); 58 while st[x3,y3-1]<>'#' do dec(y3); 59 while st[x4,y4+1]<>'#' do inc(y4); 60 mi:=min(min(min(y4-j,j-y3),x2-i),i-x1)+1; 61 if (x1<>i) and (x1<>i-1) then add(b[i,j],b[x1,y1],min(mi,i-x1)); 62 if (x2<>i) and (x2<>i+1) then add(b[i,j],b[x2,y2],min(mi,x2-i)); 63 if (y3<>j) and (y3<>j-1) then add(b[i,j],b[x3,y3],min(mi,j-y3)); 64 if (y4<>j) and (y4<>j+1) then add(b[i,j],b[x4,y4],min(mi,y4-j)); 65 end; 66 end; 67 68 procedure spfa; 69 var 70 i,h,t:longint; 71 begin 72 fillchar(d,sizeof(d),63); 73 fillchar(v,sizeof(v),0); 74 fillchar(list,sizeof(list),0); 75 h:=0; t:=1; 76 d[qq]:=0; v[qq]:=1; list[1]:=qq; 77 repeat 78 inc(h); 79 i:=ls[list[h]]; 80 while i<>0 do 81 with a[i] do 82 begin 83 if d[x]+w<d[y] then 84 begin 85 d[y]:=d[x]+w; 86 if v[y]=0 then 87 begin 88 v[y]:=1; 89 inc(t); 90 list[t]:=y; 91 end; 92 end; 93 i:=next; 94 end; 95 v[list[h]]:=0; 96 until h=t; 97 end; 98 99 begin 100 assign(input,'portal.in'); 101 assign(output,'portal.out'); 102 reset(input); 103 rewrite(output); 104 init; 105 spfa; 106 if d[zz]=d[0] then writeln('nemoguce') 107 else writeln(d[zz]); 108 close(input); 109 close(output); 110 end.