1 条题解
-
0
由于火可以蔓延到四周,人也可以前往四周(除了#的地方)所以我们可以在结构体中多加入状态p,表示当前扩散的是人还是火。注意到: 如果一个格子已经着火,或者在乔进入该格子的时刻恰好着火,则该格子对乔来说是危险的,乔不能进入该格子。 那么我们可以先扩散火 再走人 否则会因为特判问题头痛(其实是我不会写)详细见代码
#include<bits/stdc++.h> using namespace std; #define int long long int r,c,sx,sy;//行列,开始的坐标 char a[1010][1010];//地图 int dx[]={-1,1,0,0}; int dy[]={0,0,-1,1};//偏移 struct grid{ int x,y,p;//p=0时表示是人 p=1时表示火 }; int dis[1010][1010];//距离 vector<grid>f; void bfs(int x,int y,int p){ queue<grid>q; for(int i=0;i<f.size();i++){//先着火 把火全部入队 int e=f[i].x,r=f[i].y,c=f[i].p; q.push({e,r,c}); } q.push({x,y,p}); dis[x][y]=0;//人再入队 while(!q.empty()){ int tx=q.front().x,ty=q.front().y,tp=q.front().p; q.pop();//拿到队首并出队 if(tp==0){//人跑出去了 if(tx==1||tx==r||ty==1||ty==c){ cout<<dis[tx][ty]+1; return ; } } for(int i=0;i<4;i++){ int nx=tx+dx[i],ny=ty+dy[i],np=tp; if(nx>=1&&nx<=r&&ny>=1&&ny<=c&&a[nx][ny]!='#'){//不越界的同时不是障碍 if(np==0){//人 if(a[nx][ny]=='.'&&dis[nx][ny]==-1){//空地+没走过 不能走火 dis[nx][ny]=dis[tx][ty]+1;//更新距离 q.push({nx,ny,0}); } } else if(np==1){//火 if(a[nx][ny]!='F'){//注意下一个不能是火 不然会导致重复状态 a[nx][ny]='F'; q.push({nx,ny,1}); } } } } } cout<<"IMPOSSIBLE"; } signed main(){ ios::sync_with_stdio(0); cin.tie(0); cin>>r>>c; for(int i=1;i<=r;i++){ for(int j=1;j<=c;j++){ cin>>a[i][j]; dis[i][j]=-1;//初始化 if(a[i][j]=='J'){ sx=i,sy=j; } if(a[i][j]=='F'){ f.push_back({i,j,1});//把火全部放进数组中 在bfs开始时先入队 } } } if(sx==1||sx==r||sy==1||sy==c){//特判一下开局就可以跑出去 cout<<1; return 0; } bfs(sx,sy,0); }
信息
- ID
- 524
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 3
- 标签
- 递交数
- 20
- 已通过
- 4
- 上传者