2031: Barareh on Fire(預處理+bfs)
阿新 • • 發佈:2018-12-28
思路:
兩次BFS
一次處理火燒,得到每個點著火的時間,第二次bfs處理人的逃跑。
注意,像這類有多組資料輸入的時候一定要注意初始化條件,比如幾個vis陣列要置零,佇列一定要記得清空。
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<queue> using namespace std; int sx,sy,tx,ty; int n,m,k; struct node{ int x,y,time; }nextt; char mp[105][105]; int vis1[105][105]; int vis2[105][105]; int moves[8][2]={{1,0},{1,1},{1,-1},{0,1},{0,-1},{-1,1},{-1,0},{-1,-1}}; int dx[4]={1,-1,0,0}; int dy[4]={0,0,1,-1}; int mpt[105][105];//火燒時間 queue<node>q; //bfs火燒,預處理時間 void bfs_fire(){ while(!q.empty()){ node temp=q.front(); q.pop(); for(int i=0;i<8;i++){ nextt.x=temp.x+moves[i][0]; nextt.y=temp.y+moves[i][1]; nextt.time=temp.time+k; if(!vis1[nextt.x][nextt.y]&&nextt.x>=0&&nextt.y>=0&&nextt.x<n&&nextt.y<m){ mpt[nextt.x][nextt.y]=nextt.time; vis1[nextt.x][nextt.y]=1; q.push(nextt); } } } } //人逃跑 void bfs_run(){ while(!q.empty()) q.pop(); q.push((node){sx,sy,0}); vis2[sx][sy]=1; while(!q.empty()){ node temp=q.front(); q.pop(); if(temp.x==tx&&temp.y==ty){ printf("%d\n",temp.time); return ; } for(int i=0;i<4;i++){ nextt.x=temp.x+dx[i]; nextt.y=temp.y+dy[i]; nextt.time=temp.time+1; if(!vis2[nextt.x][nextt.y]&&nextt.x>=0&&nextt.y>=0&&nextt.x<n&&nextt.y<m){ if(mpt[nextt.x][nextt.y]>nextt.time){ vis2[nextt.x][nextt.y]=1; q.push(nextt); } } } } printf("Impossible\n"); return ; } int main(){ while(scanf("%d%d%d",&n,&m,&k)){ if(n==0||m==0||k==0) break; memset(vis1,0,sizeof(vis1)); memset(mp,0,sizeof(mp)); memset(mpt,0,sizeof(mpt)); memset(vis2,0,sizeof(vis2)); while(!q.empty()) q.pop(); for(int i=0;i<n;i++){ scanf("%s",mp[i]); } for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ if(mp[i][j]=='f'){ q.push((node){i,j,0}); vis1[i][j]=1; } } } for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ if(mp[i][j]=='s'){ sx=i,sy=j; } if(mp[i][j]=='t'){ tx=i,ty=j; } } } if(q.empty()) printf("%d\n",abs(tx-sx)+abs(ty-sy)); else{ bfs_fire(); bfs_run(); } } return 0; }