news 2026/6/10 16:05:30

搜索的第一次总结:水灾(flood)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
搜索的第一次总结:水灾(flood)

前几篇都讲了关于搜索的内容,现在就来做做习题吧!!!

(没看以前我的文章的人请看专栏:https://blog.csdn.net/mayuteng1/category_13083478.html?spm=1001.2014.3001.5482)

注:名字别管,其实就是Robin!!!

题目描述

这天 SB Robin 正打着游戏,正思考着怎么才能过关,突然,bong 的一声,家里的水管全爆了!!!

已知 SB Robin 的家可以用一个 n*m 的网格表示。

SB Robin 每秒钟可以走到上下左右 4 个方向的相邻格中的一个没有水的格子(他不喜欢踩水),而所有有水的格子每秒也会向四周的空格蔓延(上下左右四个格子)。显然最开始有水的格子是那些水管的位置。

SB Robin 家还有一些障碍格,比如他家的 60 英寸的大电视,比如一些紫檀木家具,还有墙也是一种障碍……,水跟 SB Robin 都不能进入这个格。

当他到达地图边界时就可以认为他逃出了他家。

请问SB Robin 怎么以最短的时间逃出家。 注意:

1.等 SB Robin 反应过来时已经过去了1秒。

2.开始时,水可能不止一处。

输入格式

第一行,两个整数 n 和 m,表示 SB Robin 家的行数跟列数。

接下来是一个 n*m 的字符串矩阵。其中,"."表示空地,水和 SB Robin 都能进去,"s"表示 SB Robin 所在位置,"w"表示爆掉的水管的位置,"#"表示障碍和墙, 水和 SB Robin 都不能进去。

输出格

输入数据仅一行,能逃出去,则输出一个整数,表示 SB Robin 逃出家的最短时间。

如果 SB Robin 出不去,则输出"IMPOSSIBLE"(不含引号)。

输入输出样例

输入数据 1

4 4 #### #sw# #..# #..#

输出数据 1

3

输入数据 2

3 4 #### #s.# #.w.

输出数据 2

IMPOSSIBLE

数据范围与约定

对于20%的数据,1<=n,m<=100;

对于100%的数据,1<=n,m<=1000。

(正在看我的博客的人在这里其实可以自己先试着打一下代码!)

————————我是分割线——————————

这题一眼搜索啊!

不过这题用DFS的话肯定会超时的(而且其实我这道题连DFS该怎么打都不知道……)!所以这道题我们只能用广度优先搜索(BFS)来做!!

代码如下:(精髓都在注释中!):

#include<bits/stdc++.h> using namespace std; long long n,m;//n,m表示矩阵的长和宽 long long a[1005][1005],xx,yy;//a数组用来判断这个地方是否是墙,xx/yy分别表示Robin的坐标 long long minn=INT_MAX;//minn表示Robin到边缘的最短距离 long long dx[]={-1,1,0,0},dy[]={0,0,-1,1};//方向数组 long long b[1005][1005],c[1005][1005];//b数组表示水流到这个地方的最短距离,c数组表示Robin到这个地方的最短距离 queue<pair<int,int>> q;//队列(用来打BFS) void bfs1()//第一个BFS,用来枚举水 { while(!q.empty()) { int x=q.front().first,y=q.front().second;//获取x和y坐标 q.pop();//弹出 for(int i=0;i<4;i++)//枚举四个方向 { int nx=x+dx[i],ny=y+dy[i]; if(nx>=1&&ny>=1&&nx<=n&&ny<=m&&b[nx][ny]==0&&a[nx][ny]!=-1) { //当x和y坐标在规定范围内且这个地方没有来过且这个地方不是墙,则加入队列 b[nx][ny]=b[x][y]+1;//标记,这个地方的步数比原来的地方的步数多一 q.push({nx,ny}); } } } } void bfs2()//第二个BFS,用来枚举Robin { q.push({xx,yy});//加入Robin的x和y坐标 while(!q.empty()) { int x=q.front().first,y=q.front().second; q.pop(); for(int i=0;i<4;i++) { int nx=x+dx[i],ny=y+dy[i]; if(nx>=1&&ny>=1&&nx<=n&&ny<=m&&c[nx][ny]==INT_MAX-1&&a[nx][ny]!=-1&&b[nx][ny]+1>c[x][y]) { //多了一个条件,那就是水流到这一格的最小步数要比Robin到这一格的最小步数多1 c[nx][ny]=c[x][y]+1;//累计 q.push({nx,ny});//加入新的x和y坐标 } } } } int main(){ cin>>n>>m; for(int i=1;i<=n;i++) { char ch; for(int j=1;j<=m;j++) { cin>>ch; if(ch=='#')a[i][j]=-1,c[i][j]=INT_MAX;//如果是墙则a[i][j]=-1,c[i][j]也要标记 else if(ch=='s')xx=i,yy=j,a[i][j]=1,c[i][j]=0;//获取Robin的坐标 else if(ch=='w')q.push({i,j}),a[i][j]=2,c[i][j]=INT_MAX;//由于可能有多处水管爆裂,所以在这里就要入队了 else c[i][j]=INT_MAX-1;//空地的话,c[i][j]=INT_MAX-1 } } bfs1();//第一个BFS bfs2();//第二个BFS //枚举矩阵的四周,假如Robin到这一格的时间比水到这一格的时间短,则minn=min(minn,Robin到这一格的时间) for(int i=1;i<=n;i++) { if(b[i][1]>c[i][1])minn=min(minn,c[i][1]); if(b[i][m]>c[i][m])minn=min(minn,c[i][m]); } for(int i=1;i<=m;i++) { if(b[1][i]>c[1][i])minn=min(minn,c[1][i]); if(b[n][i]>c[n][i])minn=min(minn,c[n][i]); } if(minn==INT_MAX)cout<<"IMPOSSIBLE";//加入minn没有更新最小值,则Robin逃离不了了 else cout<<minn+1;//否则输出minn+1 return 0; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/9 21:13:31

RepRapFirmware开源固件:3D打印机的智能控制核心终极指南

RepRapFirmware开源固件&#xff1a;3D打印机的智能控制核心终极指南 【免费下载链接】RepRapFirmware OO C RepRap Firmware 项目地址: https://gitcode.com/gh_mirrors/re/RepRapFirmware 在当今蓬勃发展的3D打印领域&#xff0c;一个高效稳定的控制固件是实现高质量打…

作者头像 李华
网站建设 2026/6/10 1:10:58

鸿蒙投屏神器HOScrcpy:零基础快速上手完整教程

鸿蒙投屏神器HOScrcpy&#xff1a;零基础快速上手完整教程 【免费下载链接】鸿蒙远程真机工具 该工具主要提供鸿蒙系统下基于视频流的投屏功能&#xff0c;帧率基本持平真机帧率&#xff0c;达到远程真机的效果。 项目地址: https://gitcode.com/OpenHarmonyToolkitsPlaza/HO…

作者头像 李华
网站建设 2026/6/10 12:19:17

18、Linux系统磁盘使用查询与软件安装管理全攻略

Linux系统磁盘使用查询与软件安装管理全攻略 1. 磁盘使用查询 在Linux系统中,有时候我们只需要知道某个目录的总使用空间,而不需要其所有子目录的详细信息。这时,可以使用 du 命令结合 -s 选项来实现。例如: $ cd music $ du -hs 2.6G .这里, du -hs 命令简洁…

作者头像 李华
网站建设 2026/6/10 1:00:00

【Redis从入门到精通,看这一篇就够了!】

在当今的后端开发领域&#xff0c;Redis绝对是一个绕不开的“明星中间件”。它以超高的性能、丰富的数据类型和灵活的使用场景&#xff0c;成为缓存、分布式锁、消息队列等场景的首选方案。很多小白在接触Redis时&#xff0c;会被“集群”“持久化”“红锁”这些概念吓倒&#…

作者头像 李华
网站建设 2026/6/9 15:25:35

重绘和重排怎么触发?怎么优化?

重绘&#xff08;Repaint&#xff09; 定义&#xff1a;元素样式改变但不影响布局时触发&#xff0c;仅重新绘制元素外观&#xff0c;不改变DOM几何结构。常见场景&#xff1a;修改color、background-color、opacity、box-shadow等。 重排&#xff08;Reflow&#xff09; 定义&…

作者头像 李华
网站建设 2026/6/10 12:23:22

[Java 并发编程] 线程池

线程池 1. 初识线程池 ​ 我们之所以引入线程&#xff0c;是因为进程的创建和销毁过于重量&#xff0c;而线程可以共享更多内存资源&#xff0c;因此成为显著提高效率的手段。但线程也是 OS 分配的&#xff0c;也涉及用户态和内核态的切换&#xff0c;也是一种很有限的资源&a…

作者头像 李华