1. 程式人生 > 其它 >1101-著火的房間(中等多源BFS問題)

1101-著火的房間(中等多源BFS問題)

技術標籤:刷題

題目描述
救救PIPI!!PIPI被關在一個著火的房間裡了!
該房間中有 nxm 個位置, 用一個字元矩陣表示。
‘s’ 代表PIPI的起點位置。
‘t’ 代表出口位置。
‘f’ 代表房間的著火點。
‘-’ 代表房間還未著火的點。
房間裡面有若干個著火點,每個著火點的移動速率是k , 意思是若一個位置在 x 時刻起火了,那麼在 x+k 時刻它周圍8個方向都會起火。
PIPI每秒能夠移動到上下左右四個方向中的一個未著火的位置。
請你程式設計計算可憐的PIPI能否成功逃離這個房間,如果PIPI能夠成功逃離這個房間,輸出PIPI逃出房間的最短時間,如果PIPI不能逃出這個房間,輸出"Impossible"。

輸入
輸入包含多組測試用例。
對於每一組測試用例,輸入第一行包含三個整數 n,m,k .分別代表房間位置的行數,列數,以及著火點的移動速率。(1<=n,m,k<=100)
接下來輸入一個n*m的字元矩陣,代表房間在0時刻的狀態。
以0 0 0 代表輸入結束。
輸出
對於每組樣例,輸出一行。如果PIPI能夠成功逃離這個房間,輸出PIPI逃出房間的最短時間,如果PIPI不能逃出這個房間,輸出"Impossible"。
樣例輸入
在這裡插入圖片描述
樣例輸出
4
Impossible
Impossible
1

題解程式碼如下:

#include<bits/stdc++.h>
using
namespace std; int n,m,k,sx,sy,fx,fy; const int N=105; const int INF=1e9; char maze[N][N]; int vis[N][N]; int dir[8][2]={0,1,0,-1,1,0,-1,0,-1,1,1,-1,1,1,-1,-1}; int fireTime[N][N]; ///記錄可著火點的著火時間 struct Node{ int x,y,t; ///表示到(x,y)點時所用的時間為t }; bool judge(int x,int y){ if(x<0||x>=
n||y<0||y>=m) return false; return true; } void getFiretime(){ //memset(fireTime,-1,sizeof fireTime); queue<Node> q; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ if(maze[i][j]=='f') fireTime[i][j]=0,q.push({i,j,0}); else fireTime[i][j]=INF; if(maze[i][j]=='s') sx=i,sy=j; if(maze[i][j]=='t') fx=i,fy=j; } } while(q.size()){ Node now = q.front();q.pop(); for(int i=0;i<8;i++){ int xx=now.x+dir[i][0],yy=now.y+dir[i][1]; if(judge(xx,yy)&&fireTime[xx][yy]==INF){ q.push({xx,yy,now.t+k}); fireTime[xx][yy]=now.t+k; } } } } void bfs(){ queue<Node> q; memset(vis,0,sizeof vis); q.push({sx,sy,0}); vis[sx][sy]=1; while(q.size()){ Node now = q.front();q.pop(); if(now.x==fx&&now.y==fy){ printf("%d\n",now.t); return; } for(int i=0;i<4;i++){ int xx=now.x+dir[i][0],yy=now.y+dir[i][1]; if(judge(xx,yy)&&vis[xx][yy]==0&&now.t+1<fireTime[xx][yy]){ q.push({xx,yy,now.t+1}); vis[xx][yy]=1; } } } printf("Impossible\n"); } int main(){ while(~scanf("%d%d%d",&n,&m,&k)&&n+m+k){ for(int i=0;i<n;i++) scanf("%s",maze[i]); getFiretime(); ///將著火點預處理 bfs(); } return 0; }