jzoj 1350. 【2011.12.17普及模拟】流星雨

题目描述
   贝茜听说了一个骇人听闻的消息:一场流星雨即将袭击整个农场,由于流星体积过大,它们无法在撞击到地面前燃烧殆尽,届时将会对它撞到的一切东西造成毁灭性的打击。很自然地,贝茜开始担心自己的安全问题。以FJ牧场中最聪明的奶牛的名誉起誓,她一定要在被流星砸到前,到达一个安全的地方(也就是说,一块不会被任何流星砸到的土地)。如果将牧场放入一个直角坐标系中,贝茜现在的位置是原点,并且,贝茜不能踏上一块被流星砸过的土地。

    根据预报,一共有M颗流星(1 <= M <= 50,000)会坠落在农场上,其中第i颗流星会在时刻T_i (0 <= T_i <= 1,000)砸在坐标为(X_i, Y_i) (0 <= X_i <= 300;0 <= Y_i <= 300)的格子里。流星的力量会将它所在的格子,以及周围4个相邻的格子都化为焦土,当然贝茜也无法再在这些格子上行走。

    贝茜在时刻0开始行动,它只能在第一象限中,平行于坐标轴行动,每1个时刻中,她能移动到相邻的(一般是4个)格子中的任意一个,当然目标格子要没有被烧焦才行。如果一个格子在时刻t被流星撞击或烧焦,那么贝茜只能在t之前的时刻在这个格子里出现。

    请你计算一下,贝茜最少需要多少时间才能到达一个安全的格子。
输入
第1行: 1个正整数:M

第2..M+1行: 第i+1行为3个用空格隔开的整数:X_i,Y_i,以及T_i
输出
   第1行: 输出1个整数,即贝茜逃生所花的最少时间。如果贝茜无论如何都无法         在流星雨中存活下来,输出-1。
样例输入
4
0 0 2
2 1 2
1 1 2
0 3 5
样例输出
5
数据范围限制
提示
【样例说明】

    一共有4颗流星将坠落在农场,它们落地点的坐标分别是(0, 0),(2, 1),(1, 1)以及(0, 3),时刻分别为2,2,2,5。      

    t = 0                t = 2              t = 5

5|. . . . . . .     5|. . . . . . .     5|. . . . . . .   

4|. . . . . . .     4|. . . . . . .     4|# . . . . . .   * = 流星落点

3|. . . . . . .     3|. . . . . . .     3|* # . . . . . 

2|. . . . . . .     2|. # # . . . .     2|# # # . . . .   # = 行走禁区

1|. . . . . . .     1|# * * # . . .     1|# # # # . . .  

0|B . . . . . .     0|* # # . . . .     0|# # # . . . .  

 --------------      --------------      --------------

 0 1 2 3 4 5 6       0 1 2 3 4 5 6       0 1 2 3 4 5 6

如果我们观察在t=5时的牧场,可以发现离贝茜最近的安全的格子是(3,0)——不过由于早在第二颗流星落地时,贝茜直接跑去(3,0)的路线就被封死了。离贝茜第二近的安全格子为(4,0),但它的情况也跟(3,0)一样。再接下来的格子就是在(0,5)-(5,0)这条直线上。在这些格子中,(0,5),(1,4)以及(2,3)都能在5个单位时间内到达。

       5|. . . . . . .  

       4|. . . . . . .  

       3|3 4 5 . . . .    某个合法的逃生方案中

       2|2 . . . . . .    贝茜每个时刻所在地点

       1|1 . . . . . .  

       0|0 . . . . . .  

         --------------

         0 1 2 3 4 5 6 

这道题我用的是广搜 代码如下:

const
 x:array[1..4]of integer=(1,-1,0,0);
 y:array[1..4]of integer=(0,0,1,-1);
var
 e:array[-30..410,-30..410]of longint; //这里下限-1其实就可以了,上限也不用开那么大,302就可以,因为流星只能在300之内,最多影响到301
 a:array[-30..410,-30..410]of boolean;
 n:longint;
 s:array[1..1001*1001,1..2]of longint; // 这里数组其实可以不用开那么大
 f,ti:array[0..1001*1001]of longint; //
procedure init
var i,j,k,l:longint;
begin
 readln(n);
 for i:=-1 to 301 do 
  for j:=-1 to 301 do
   e[i,j]:=maxlongint; //先赋一个最大值
  for i:=1 to n do
   begin
    readln(k,j,l); //题目中行和列是反的。。。所以我们也反一下
    if l<e[j,k] then e[j,k]:=l;      //这个地方这样做是因为有些流星波及到的区域可能会重复,那么,本来一个地方很早就不能走了(被流星波及到)但后来又有一个
                                        流星波及到,并且时间比之前的晚,就会覆盖掉之前的时间
    if l<e[j+1,k] then e[j+1,k]:=l;   
    if l<e[j-1,k] then e[j-1,k]:=l;
    if l<e[j,k-1] then e[j,k-1]:=l;
    if l<e[j,k+1] then e[j,k+1]:=l;
   end;
end;

procedure  bfs;
var i,j,k,h,t:longint;
begin
 h:=0; t:=1; a[0,0]:=true;
 repeat
  inc(h);
  for i:=1 to 4 do
   if (s[h,1]+x[i]>=0)and(s[h,2]+y[i]>=0) then
    if (e[s[h,1]+x[i],s[h,2]+y[i]]>ti[h]+1)and(not a[s[h,1]+x[i],s[h,2]+y[i]])
    then
     begin
      inc(t);
      f[t]:=h;
      ti[t]:=ti[f[t]]+1;
      s[t,1]:=s[h,1]+x[i];
      s[t,2]:=s[h,2]+y[i];
      a[s[t,1],s[t,2]]:=true;
     if e[s[t,1],s[t,2]]=maxlongint then begin writeln(ti[t]); close(input); close(output); halt; end;
     end;
  until h>t;
end;

begin
 assign(input,'meteor.in');reset(input);
 assign(output,'meteor.out');rewrite(output);
 init;
 bfs;
 writeln(-1);
 close(input); close(output);
end.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值