洛谷P2895Meteor Shower S

文章讲述了如何利用BreadthFirstSearch(BFS)算法解决一个IT技术问题,计算贝茜在流星雨影响下到达安全位置的最短时间,避开流星坠落区域。

题目描述

贝茜听说一场特别的流星雨即将到来:这些流星会撞向地球,并摧毁它们所撞击的任何东西。她为自己的安全感到焦虑,发誓要找到一个安全的地方(一个永远不会被流星摧毁的地方)。

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

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

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

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

输入格式

共 M+1 行,第 1 行输入一个整数 M,接下来的 M 行每行输入三个整数分别为Xi​,Yi​,Ti​。

输出格式

贝茜到达安全地点所需的最短时间,如果不可能,则为 −1。

这道题刚拿到手我的思路并不是bfs而是暴力,方块进行遍历,如果安全,用行数列数相减就可以计算出步数,但是好像不太对,直接放弃。老老实实用bfs写。

最开始思路就是用一个二维数组star,将流星落下的位置以及周围四个位置赋值为落下的时间,但是还是要分析先后顺序,如果重复赋值要取最小的那个时间值。然后就是从(0,0)开始遍历,本来是想着省变量直接在star数组上面搜索,写了半天总有小错误,直接也不省变量了,又开一个二维数组g用来记录步数。不过需要注意的是,将star数组初始化为1e9,也就是无穷大,代表方块永远没有流星落下。接下来就是模板了,直接上代码

变量解释

star:记录流行落下时间及坐标

g:记录步数

go:偏移量数组

cont队列:这就不必解释了吧应该

//Meteor Shower S
#include "iostream"
#include "queue"
#include "cstring"
using namespace std;
int n;
int star[305][305];
int g[305][305];
int go[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
typedef pair<int,int>pos;
queue<pos>cont;
int bfs(){
    cont.push({0,0});//起点进队
    while(!cont.empty()){//标准模板
        pos temp=cont.front();
        int x=temp.first,y=temp.second;
        cont.pop();
        for(int i=0;i<4;i++){//找四个方向
            int nx=x+go[i][0],ny=y+go[i][1];
            if(nx<0||ny<0)continue;//超限,过掉
            if(g[nx][ny])continue;//走过,剪枝过掉,一个格子永远不重复走第二次
            if(g[x][y]+1>=star[nx][ny])continue;//步数大于等于流星落下的那么会被砸死,过掉
            g[nx][ny]=g[x][y]+1;//所有不被过掉的坐标都可以走,赋值为+1
            cont.push({nx,ny});//入队,为了下次遍历
            if(star[nx][ny]>1e9)return g[nx][ny];//如果这个方格可以走并且不会被砸,直接返回走到此格所需步数
        }
    }
    return -1;//中间一直没有return就代表无法走出返回-1
}
int main(){
    cin>>n;
    memset(star,0x3f,sizeof star);//初始化为无穷大
    for(int i=0;i<n;i++){
        int x,y,flag;
        cin>>x>>y>>flag;//输入条件,flag为落下时间
        star[x][y]=min(star[x][y],flag);//取最小时间
        for(int j=0;j<4;j++){//四个方向赋值
            int nx=x+go[j][0],ny=y+go[j][1];
            if(nx<0||ny<0)continue;//超限,过掉
            star[nx][ny]=min(star[nx][ny],flag);//依然是取最早的时间,也就是最小值
        }
    }
    int ans=bfs();
    cout<<ans;//输出结果
}

<think>嗯,用户想找平台上关于宽度优先搜索的经典题目推荐。首先,我需要回忆一下BFS的常见应用场景,比如最短路径、状态搜索等。然后根据的题库,有哪些题目是经典且适合练习BFS的。 记得用户之前提到过BFS在权值为1的最短路问题中的应用,比如马的遍历,这可能对应P1443。另外,迷宫类问题也是BFS的典型,比如P1162填涂颜色,可能需要用BFS来扩展区域。还有P1135奇怪的电梯,每个楼层可以看作一个状态,通过按钮上下层数作为状态转移,适合BFS求最短按按钮次数。 另外,八数码问题,比如P1379,属于经典的状态搜索,可能需要用BFS配合哈希来记录状态,同时处理步数。还有像P1141迷宫这样的题目,虽然可能有多个查询,但可以预先用BFS处理连通块,记录每个点的所属区域,这样查询时就能快速给出答案。 要注意题目的难度梯度,从基础到进阶排列。比如先推荐二维网格中的基础BFS,如马的遍历,再逐渐过渡到状态空间更大的问题,如八数码。同时要确保推荐的题目在上确实存在,且是用户普遍认为的经典题。 另外,用户可能希望了解每道题目的考察重点,比如最短路径、状态压缩、连通块处理等,所以在推荐时需要简要说明每道题的特点和解题思路,帮助用户理解为什么选择这些题目。还要考虑题目的通过率和难度系数,确保推荐的题目适合不同阶段的学习者。 最后,需要检查引用内容是否相关,用户提供的引用中提到BFS用于边权为1的最短路,如马的遍历和迷宫问题,这些都需要在推荐中体现,正确标注引用来源。比如引用[3]和[4]都提到了BFS的最短路径特性,适合用来支持题目的选择理由。</think>根据平台的经典题目和宽度优先搜索(BFS)的核心应用场景,以下是精心筛选的题目推荐及解析: --- ### 一、基础网格类BFS 1. **P1443 马的遍历** - **考察重点**:棋盘上单源最短路径的标准化实现 - **特点**:马走日字形移动,需处理8个方向的BFS扩展 - **关键技巧**:用`dist[][]`数组记录步数,初始值设为-1表示未访问[^3][^4] 2. **P1162 填涂颜色** - **考察重点**:连通区域标记与边界处理 - **特点**:通过逆向思维,从边缘BFS标记非闭合区域 - **解题提示**:将矩阵扩大一圈避免边界判断错误 --- ### 二、状态空间类BFS 3. **P1135 奇怪的电梯** - **考察重点**:抽象状态的定义与转移 - **特点**:将楼层编号视为状态节点,按钮操作视为状态转移 - **代码框架**: ```python queue = deque() visited = [False]*(n+1) queue.append((start, 0)) # (当前楼层, 步数) ``` 4. **P1379 八数码难题** - **考察重点**:状态压缩与哈希判重 - **难点**:将3x3矩阵转化为字符串存储状态 - **优化**:使用双向BFS大幅减少搜索空间 --- ### 三、进阶应用类BFS 5. **P1141 01迷宫** - **考察重点**:预处理连通块 - **特性**:多个查询时,通过一次BFS标记所有连通区域 - **技巧**:建立连通块编号与区域大小的映射表[^4] 6. **P1825 [USACO11OPEN]Corn Maze S** - **考察重点**:复杂场景下的状态管理 - **特殊机制**:传送门处理、多层级状态判断 - **注意点**:需记录经过传送门后的新坐标 --- ### 四、特殊变式类BFS 7. **P1902 刺杀大使** - **考察重点**:二分答案+BFS验证 - **创新点**:将"最大值最小化"问题转化为判定性问题 - **实现步骤**: 1. 二分猜测伤害值 2. BFS验证是否存在通路 8. **P2895 [USACO08FEB]Meteor Shower S** - **考察重点**:动态变化的搜索空间 - **时间维度**:每个格子的危险时间需要预处理 - **关键点**:人物移动与陨石降落的时间轴同步处理 --- ### 训练建议 1. 按顺序从基础网格题开始,逐步过渡到状态空间类题目 2. 调试时打印队列状态和访问数组,可视化BFS过程 3. 对比DFS实现,体会两种搜索方式的本质差异[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值