[USACO08FEB]Meteor Shower S

题目描述

Bessie hears that an extraordinary meteor shower is coming; reports say that these meteors will crash into earth and destroy anything they hit. Anxious for her safety, she vows to find her way to a safe location (one that is never destroyed by a meteor) . She is currently grazing at the origin in the coordinate plane and wants to move to a new, safer location while avoiding being destroyed by meteors along her way.

The reports say that M meteors (1 ≤ M ≤ 50,000) will strike, with meteor i will striking point (Xi, Yi) (0 ≤ Xi ≤ 300; 0 ≤ Yi ≤ 300) at time Ti (0 ≤ Ti ≤ 1,000). Each meteor destroys the point that it strikes and also the four rectilinearly adjacent lattice points.

Bessie leaves the origin at time 0 and can travel in the first quadrant and parallel to the axes at the rate of one distance unit per second to any of the (often 4) adjacent rectilinear points that are not yet destroyed by a meteor. She cannot be located on a point at any time greater than or equal to the time it is destroyed).

Determine the minimum time it takes Bessie to get to a safe place.

输入格式

* Line 1: A single integer: M

* Lines 2…M+1: Line i+1 contains three space-separated integers: Xi, Yi, and Ti

输出格式

* Line 1: The minimum time it takes Bessie to get to a safe place or -1 if it is impossible.

题目翻译

贝茜听说了一个骇人听闻的消息:一场流星雨即将袭击整个农场,由于流星体积过大,它们无法在撞击到地面前燃烧殆尽,届时将会对它撞到的一切东西造成毁灭性的打击。很自然地,贝茜开始担心自己的安全问题。

以 Farmer John 牧场中最聪明的奶牛的名誉起誓,她一定要在被流星砸到前,到达一个安全的地方(也就是说,一块不会被任何流星砸到的土地)。

如果将牧场放入一个直角坐标系中,贝茜现在的位置是原点,并且,贝茜不能踏上一块被流星砸过的土地。

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

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

请你计算一下,贝茜最少需要多少时间才能到达一个安全的格子。如果不可能到达输出 −1-1−1。

Translated by @奆奆的蒟蒻 @跪下叫哥

输入格式

* 第一行: 一个整数M

* 第2行到第m+1行: 每一行包含三个整数Xi,Yi,Ti,具体意思见题目描述。

输出格式

*输出一共一行: Bessie逃到一个安全区域的最短时间;如果Bessie不能逃到安全区域,则输出-1。

样例 #1

样例输入 #1

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

样例输出 #1

5

解析

作为NOIP 2017普及组的参赛者之一,这道题还是很亲切的。为何?因为当年的第三题——棋盘,对众多编程大佬眼中只是一道水的不能再水的题目,而对于我,却有不同寻常的意义。我也许没有成就那道题,但是那道题却成就了我。换句话说,没有那道题,或者没有解出来那道题,我轨迹大概率会和现在不同。

至于我为何会这么说,在后续的文章里我会重温NOIP 2017普及组,尤其是第三题——棋盘。我知道,在这个急功近利的时代,内卷激烈的时代,人们往往更注重结果;而我认为,结果固然重要,但在过程中你收获了什么、吸取了什么教训、有哪些进步、有哪些破茧成蝶…同样具有重大意义。因为有些能力是可以作用于很多方面上的。

闲话少说,进入正题。

对于这道题而言,想都不用想,肯定是深度优先搜索(以下简称dfs)。这道题源于跳马和棋盘,又比跳马和棋盘更具有挑战性,因为这个矩阵的边界比较模糊(指的是只能依靠数据范围去定边界,而不是输入m和n来控制矩阵的边界)。

下面是我的思考过程

1、dfs是递归的一种,凡是递归,想都不用想,一定要有出口:当坐标(x,y)不会被烧毁的时候,就return并且记录时间。

2、其次就是参数了,x,y,t分别表示横坐标、纵坐标和时间。

3、定义一个方向数组,控制四个方向:

fx[4][2]={{0,1},{1,0},{0,-1},{-1,0}}

然后循环四次确定新的坐标,只不过要注意新的坐标必须遵守以下规则:
1)不能越界
2)第t+1时刻到达那里的时候格子没有被烧毁

思考到这一步,整个程序的基本框架就出来了。在输入流星和会烧毁的坐标的时候,就要进行处理。只不过要注意以下三点:

1、要处理爆炸中心(x,y)和它周边的四个格子;

2、小心越界,程序报错。就是如果砸到边界,那越界的格子就不要处理,因为数组的下标必须是非负整数。

3、当流星雨比较密集的时候,要注意一个格子可能会在多个流星雨的烧毁范围内。这时候,就需要取最早的烧毁时间。

打个广告:写程序,学英语。 流星的英文是meteor,那我就用meteor做二维数组,记录某个坐标(x,y)和它最早的被烧毁时间。当然,由于要比大小,所以要先把整个meteor数组初始化为一个很大的数。

再开设一个bool型标志变量二维数组b,来记录某个格子最终是否被烧毁。 那很显然,在递归的时候如果走到一个自始至终都不会被烧毁的格子,那么这就是一种可行的方案,然后结束递归记录答案比大小。 这就是递归的出口!

优化处理:
再增设一个二维数组ti,来记录走到(x,y)时刻用的时间。如果某一次走到了一个坐标(x,y),而用时却比前面某一次走到这个位置的时间要长,那显然这不是最优解,递归也没有必要继续执行下去了,直接return。

由于涉及取最小值,还是要把整个二维数组ti初始化为一个很大的数。

经过以上思考,程序就出来了。下面双手奉上AC代码:

//#include<bits/stdc++.h>//有的编译器可能不允许使用万能库
#include<iostream>
#include<cstring>
using namespace std;
const int N=1002;
int fx[4][2]={{0,1},{1,0},{0,-1},{-1,0}},ans=1e9,m,ti[N][N],meteor[N][N];
bool b[N][N];
void dfs(int x,int y,int t)
{if(!b[x][y]){ans=min(ans,t);ti[x][y]=t;return;}if(t>=ti[x][y]) return;ti[x][y]=t;int xx,yy;for(int i=0;i<4;i++){xx=x+fx[i][0];yy=y+fx[i][1];if(xx<0||yy<0||t+1>=meteor[xx][yy]) continue;dfs(xx,yy,t+1);}
}
int main()
{memset(ti,0x2f,sizeof(ti));memset(meteor,0x2f,sizeof(meteor));cin>>m;int x,y,t;for(int i=1;i<=m;i++){cin>>x>>y>>t;b[x][y]=1;meteor[x][y]=min(meteor[x][y],t);b[x+1][y]=1;meteor[x+1][y]=min(meteor[x+1][y],t);b[x][y+1]=1;meteor[x][y+1]=min(meteor[x][y+1],t);if(x-1>=0){b[x-1][y]=1;meteor[x-1][y]=min(meteor[x-1][y],t);}if(y-1>=0){b[x][y-1]=1;meteor[x][y-1]=min(meteor[x][y-1],t);}}/*for(int i=0;i<7;i++)//检查预处理是否正确{for(int j=0;j<7;j++)cout<<b[i][j]<<" ";cout<<endl;}cout<<endl;for(int i=0;i<7;i++){for(int j=0;j<7;j++)cout<<meteor[i][j]<<" ";cout<<endl;}*/dfs(0,0,0);if(ans==1e9) ans=-1;cout<<ans<<endl;
}

再放上来一个没有任何注释的版本

#include<iostream>
#include<cstring>
using namespace std;
const int N=1002;
int fx[4][2]={{0,1},{1,0},{0,-1},{-1,0}},ans=1e9,m,ti[N][N],meteor[N][N];
bool b[N][N];
void dfs(int x,int y,int t)
{if(!b[x][y]){ans=min(ans,t);ti[x][y]=t;return;}if(t>=ti[x][y]) return;ti[x][y]=t;int xx,yy;for(int i=0;i<4;i++){xx=x+fx[i][0];yy=y+fx[i][1];if(xx<0||yy<0||t+1>=meteor[xx][yy]) continue;dfs(xx,yy,t+1);}
}
int main()
{memset(ti,0x2f,sizeof(ti));memset(meteor,0x2f,sizeof(meteor));cin>>m;int x,y,t;for(int i=1;i<=m;i++){cin>>x>>y>>t;b[x][y]=1;meteor[x][y]=min(meteor[x][y],t);b[x+1][y]=1;meteor[x+1][y]=min(meteor[x+1][y],t);b[x][y+1]=1;meteor[x][y+1]=min(meteor[x][y+1],t);if(x-1>=0){b[x-1][y]=1;meteor[x-1][y]=min(meteor[x-1][y],t);}if(y-1>=0){b[x][y-1]=1;meteor[x][y-1]=min(meteor[x][y-1],t);}}dfs(0,0,0);if(ans==1e9) ans=-1;cout<<ans<<endl;
}

手敲代码不易,麻烦路过的看过留下一个赞或者评论。当然,如果有什么意见或建议也欢迎在评论区留言。

关注博主,可以看到更多内容哦~

不久之后将在CSDN更新NOIP 2017 普及组的那些往事,以自勉,以共勉。

P2895 [USACO08FEB]Meteor Shower S相关推荐

  1. 洛谷 P2895 [USACO08FEB]Meteor Shower S C++ BFS 广搜

    题目描述 Bessie hears that an extraordinary meteor shower is coming; reports say that these meteors will ...

  2. bfs总结 bfs题单 最短路 python (奇怪的电梯 好奇怪的游戏 迷宫 马的遍历 [USACO08FEB]Meteor Shower S)

    1 可以用来遍历所有的点 2 可以用来找最短路 3 多源最短路,开始时一次向队列放之多个点#板子 """ def bfs():1 起始点入队标记入队的点while not ...

  3. 玉米迷宫,Meteor Shower S,单词接龙

    玉米迷宫:- [P1825 [USACO11OPEN]Corn Maze S](https://www.luogu.com.cn/problem/P1825) 这是让我卡了整整一天的题目,虽然说思路不 ...

  4. bzoj 1611: [Usaco2008 Feb]Meteor Shower流星雨(DP)

    1611: [Usaco2008 Feb]Meteor Shower流星雨 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 1631  Solved: 6 ...

  5. 【POJ - 3669】Meteor Shower(bfs)

    -->Meteor Shower 直接上中文了 Descriptions: Bessie听说有场史无前例的流星雨即将来临:有谶言:陨星将落,徒留灰烬.为保生机,她誓将找寻安全之所(永避星坠之地) ...

  6. POJ 3669 Meteor Shower

    暴力DFS. 有2个剪枝: 1.记录一下走到某一格的最小步数 2.走到安全地点马上return WA点:安全地点坐标不一定在300以内! #include<cstdio> #include ...

  7. poj3669 Meteor Shower(预处理+bfs)

    https://vjudge.net/problem/POJ-3669 先给地图a[][]预处理每个位置被砸的最小时间.然后再bfs. 纯bfs,还被cin卡了下时间.. 1 #include< ...

  8. (BFS)Meteor Shower (poj3669)

    题目: Bessie听说有场史无前例的流星雨即将来临:有谶言:陨星将落,徒留灰烬.为保生机,她誓将找寻安全之所(永避星坠之地).目前她正在平面坐标系的原点放牧,打算在群星断其生路前转移至安全地点. 此 ...

  9. POJ 3669 Meteor Shower 流星雨 解题思路心得 BFS广搜 C/C++AC代码(另有TLE不知其因)

    原题 http://poj.org/problem?id=3669 题意 贝西(Bessie)听说即将发生一场异常的流星雨;有报道称这些流星将坠入大地并摧毁其所击中的任何东西,为安全着急,她发誓要找到 ...

最新文章

  1. 什么样的技术将在后大流行的世界里兴起
  2. [转载]Python方法绑定——Unbound/Bound method object的一些梳理
  3. [Java基础]自动装箱和拆箱
  4. 微软CEO:人工智能应该帮助而非取代劳动者
  5. 【C#】详解C#异常
  6. Python还能走多远?
  7. Caused by: com.mysql.jdbc.PacketTooBigException: Packet for query is too large (1696 1024)
  8. 线性代数【八】二次型
  9. 完美数c语言程序_C中的完美数
  10. UFS 3.1协议分析(第五章) -- UFS协议栈
  11. 【02】一个实现h5的拖放的整个过程-魔芋
  12. php取网盘真实链接,【已解决】获取蓝奏云真实链接问题?
  13. 【深度学习-机器学习】分类度量指标 : 正确率、召回率、灵敏度、特异度,ROC曲线、AUC等
  14. mips汇编之利用syscall输出结果
  15. 【20180125】【Matlab】矩阵对列、行、所有元素求和
  16. Matlab-稀疏矩阵
  17. Android-开发之从掉洞到填坑之路,走进Android架构
  18. 2016-JavaScript之星
  19. 网络:认识网络字节序
  20. 苹果手机技巧,如何查男朋友手机,查岗技能大曝光!

热门文章

  1. Clion新UI体验,墙裂推荐,用起来真的好爽啊!
  2. havc是什么意思_H.264/AVC是什么?
  3. 圆桌共话:如何冲破数据高墙,连线“数智未来”?
  4. 那些年啊,那些事——一个程序员的奋斗史 ——53
  5. 如何用神经网络预测股票趋势?
  6. 【基于可见光定位的智能超市购物车系统】(四)可见光定位、电机驱动与整车设计
  7. matplotlib8 -- 文字注释进一步详解 bbox参数, 箭头形状等
  8. java API文档中文版 网盘下载
  9. Android——透明色
  10. sklearn_决策树