zoukankan      html  css  js  c++  java
  • 5781. 【NOIP提高A组模拟2018.8.8】秘密通道

    Description

    有一副n*m的地图,有n*m块地,每块是下列四种中的一种:
    墙:用#表示,墙有4个面,分别是前面,后面,左面,右面。
    起点:用C表示,为主角的起点,是一片空地。
    终点:用F表示,为主角的目的地,是一片空地。
    空地:用 . 表示。
    其中除了墙不能穿过,其他地方都能走。
    主角有以下3种操作:
    1.移动到相邻的前后左右的地方,花费一个单位时间。
    2.向前后左右其中一个方向发射子弹,子弹沿直线穿过,打在最近的一堵墙的一面,然后墙的这面就会形成一个开口通往秘密通道。同一时间最多只能有两个开口,若出现有3个开口,出现时间最早的开口会立即消失。该操作不用时间。
    3.可以从一个与开口相邻的空地跳进去,进入秘密通道,从另外一个开口正对的空地跳出来。这个过程花费一个单位时间。
    地图四周都是墙,问主角最少用多少时间从C走到F。C和F只会出现一次。
     
     
    Input
    第一行输入两个正整数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.
  • 相关阅读:
    值得收藏的14款响应式前端开发框架
    简单几步把LOGO变字体
    7 款免费的 Metro UI 模板
    JPG渐进 & PNG/PNG24 交错测试
    你的钱,以后是放银行还是放支付宝?
    Bise IE6 在你的网站上加上它让IE滚蛋吧
    单例模式常见场景
    10 个最新的开发者工具
    大流量网站的底层系统架构
    DNS解析全过程及原理
  • 原文地址:https://www.cnblogs.com/zyx-crying/p/9445519.html
Copyright © 2011-2022 走看看