首页 > 其他分享 >10.起火迷宫(简单搜索 多源BFS)

10.起火迷宫(简单搜索 多源BFS)

时间:2023-05-02 21:13:05浏览次数:69  
标签:10 dj int 迷宫 BFS df 方格 jx 多源

起火迷宫

↑ 题目链接

题目

一个迷宫可以看作一个 \(R\) 行 \(C\) 列的方格矩阵。
其中一些方格是空地,用 . 表示,其他方格是障碍,用 # 表示。
开始时,乔位于一块空地之中。
迷宫中一些空地已经起火了,幸运的是火还没有蔓延至乔所在的位置。
为了避免被火烧伤,乔需要尽快逃离迷宫。
已知,乔每单位时间只能沿上下左右四个方向前进一格距离,并且在前进过程中,他不能进入障碍方格。
火每单位时间都会蔓延至其上下左右四个方向的相邻空地,但是火也会被障碍阻挡。
如果一个方格已经起火或者会在乔进入方格的那一时刻恰好起火,则该方格很危险,乔不能进入。
当乔进入到任意一个位于边界的空地方格时,他都可以再花费一单位时间,直接逃离迷宫。
请问,乔想要逃离迷宫,最少需要花费的时间。

输入格式

第一行包含整数 \(T\),表示共有 \(T\) 组测试数据。
每组数据第一行包含两个整数 \(R,C\)
接下来 \(R\) 行,包含一个 \(R×C\) 的字符矩阵。
矩阵中只包含以下四种字符:

# 表示障碍方格。
. 表示空地方格。
J 表示乔所在的空地方格,最多只有一个。
F 表示已经起火的空地方格。

输出格式

每组数据输出一行结果,一个整数表示逃离迷宫所需花费的最少时间,如果无法逃离迷宫,则输出 IMPOSSIBLE

数据范围

\(1≤T≤10,1≤R,C≤1000\)

输入样例:

2
4 4
####
#JF#
#..#
#..#
3 3
###
#J.
#.F

输出样例:

3
IMPOSSIBLE

思路

两次 \(BFS\) 搜索,只要到达这个格子的时间严格小于这个格子被火覆盖的时间,就能走到这个格子,特判开始在边界的情况

代码

#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
const int N=1010;
typedef pair<int,int>PII;
char g[N][N];
bool st[N][N];
int df[N][N],dj[N][N];
int n,m;
int jx,jy;
int dx[]={-1,0,1,0},dy[]={0,1,0,-1};
vector<PII>fire;

//求出所有格子被火覆盖的最短时间(多源bfs, 有多个火种)
void bfs_f()
{
    
    memset(df,-1,sizeof df);
    queue<PII>q;
    
    for(auto t:fire)
    {
        q.push({t.x,t.y});
        df[t.x][t.y]=0;
    }
    
    while(q.size())
    {
        auto t=q.front();
        q.pop();
        
        for(int i=0;i<4;i++)
        {
            int a=t.x+dx[i],b=t.y+dy[i];
            if(a<0||a>=n||b<0||b>=m||g[a][b]=='#'||df[a][b]!=-1)continue;
            df[a][b]=df[t.x][t.y]+1;
            q.push({a,b});
        }
    }
   
}

//再从起点开始bfs, 只要到达这个格子的时间严格小于这个格子被火覆盖的时间,就能走到这个格子
int bfs_j()
{
    memset(dj,-1,sizeof dj);
    queue<PII>q;
    
    q.push({jx,jy});
    dj[jx][jy]=0;
    if(jx==0||jx==n-1||jx==0||jx==m-1)return 1;//一开始在边界
    while(q.size())
    {
        auto t=q.front();
        q.pop();
        
        for(int i=0;i<4;i++)
        {
            int a=t.x+dx[i],b=t.y+dy[i];
            if(a<0||a>=n||b<0||b>=m||g[a][b]=='#'||dj[a][b]!=-1||g[a][b]=='F')continue;
            if(df[a][b]!=-1&&dj[t.x][t.y]+1>=df[a][b])continue;
            dj[a][b]=dj[t.x][t.y]+1;
            if(a==0||a==n-1||b==0||b==m-1)return dj[a][b]+1;
            q.push({a,b});
        }
    }    
    
    return -1;
}

int main()
{
	int T;
	cin>>T;
	while(T--)
	{
	    fire.clear();
		cin>>n>>m;
		for(int i=0;i<n;i++)
			for(int j=0;j<m;j++)
			{
				cin>>g[i][j];
				if(g[i][j]=='J')jx=i,jy=j;
				if(g[i][j]=='F')fire.push_back({i,j});
			}
		
	    bfs_f();
	    
	    int t=bfs_j();  

	    if(t==-1)puts("IMPOSSIBLE");
	    else cout<<t<<endl;
	    
	}
	
	
	return 0;
}

标签:10,dj,int,迷宫,BFS,df,方格,jx,多源
From: https://www.cnblogs.com/zzmxj/p/17368263.html

相关文章

  • 12.石油储备(简单搜索 DFS/BFS 统计连通块个数)
    石油储备题目一片土地可以看作是一个\(n\)行\(m\)列的方格矩阵。其中一些方格藏有石油,用@表示,其余方格没有石油,用*表示。每个方格都与其上、下、左、右、左上、右上、左下、右下八个方格视为相邻。如果两个藏有石油的方格相邻,则它们被认为是处于同一片油田,否则它们被......
  • 14.找路(简单搜索 BFS 最短步数)
    找路↑题目链接题目给定一个\(n\)行\(m\)列的方格矩阵。其中有些方格是空地(可以进入),有些方格是餐厅(可以进入),有些方格是障碍(不可进入)。开始时,小\(Y\)和小\(M\)各自位于一个空地方格中。每个人都可以沿上下左右四个方向进行移动,移动一格距离需要花费\(11\)分钟时间。......
  • AT_abc106_d [ABC106D] AtCoder Express 2 题解
    题目传送门解题思路区间\(dp\)。划分阶段:以左右城市之间的列车数量为阶段。状态表达:设\(f_{i,j}\)为城市\(i\)与城市\(j\)之间的列车数量。状态转移:由图可知,城市\(l\)与城市\(r\)之间的列车数量,就是城市\(l\)与城市\(r-1\)之间的列车数量与城市\(l+1\)与......
  • Oracle ORA-01033: ORACLE initialization or shutdown in progress(误删了DBF数据库
    先声明一下前期的一些手欠欠儿的操作导致oracl登录不进去了,起先是清理磁盘空间的时候误删除了orcleDBF数据文件后无法进入系统,plsql登录报错如下:一般情况下,删除表空间的正确方法是:DROPTABLESPACEBDCDJINCLUDINGCONTENTSANDDATAFILES;如果没有通过以上命令删除而直接删除......
  • 9.点火游戏(简单搜索 BFS)
    点火游戏↑题目链接题目给定一个\(N\)行\(M\)列的方格矩阵。其中一部分方格是草地,其余部分是空地。草地能够被燃烧,空地不会。当某个草地在\(t\)时刻被点燃时,其上下左右四个方向的相邻方格中的草地方格也会在\(t+1\)时刻被点燃。注意,空地方格无论如何都不可能被点燃。......
  • 11.迷宫问题(BFS 储存路径)
    迷宫问题↑题目链接题目给定一个\(n×n\)的二维数组,如下所示:intmaze[5][5]={0,1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,0,};它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上......
  • 13.非常可乐(简单搜索 BFS)
    非常可乐题目大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子,它们的容量分别是\(N\)毫升和\(M\)毫升。可......
  • NC20279 [SCOI2010]序列操作
    题目链接题目题目描述lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作:0ab把[a,b]区间内的所有数全变成01ab把[a,b]区间内的所有数全变成12ab把[a,b]区间内的所有数全部取反,也就是说把所有的0变成1,......
  • 考研周记-week10
    迟来的周记4.24~4.30记录一下本周的考研进度情况英语截止到目前,考研大纲词汇还剩500词,预计5月10号之前背完一轮大纲词汇,然后开始重复复习。同时根据情况决定是否学习语法和阅读。数学数学方面,本周还是再做张宇的1000题,但是做到积分的时候,就没有往下做了,准备换一本题,因为1000......
  • 10 ETH-TheDAO
    《区块链技术与应用》课程链接:https://www.bilibili.com/video/BV1Vt411X7JF/?spm_id_from=333.337.search-card.all.click10ETH-TheDAO目录10ETH-TheDAO重入攻击比特币——>去中心化货币以太坊——>去中心化合约DAO(DecentralizedAutonomousOrganization):TheDAO就......