1. 程式人生 > >UVA11624 Fire!【BFS】

UVA11624 Fire!【BFS】

問題描述:在一個R x C的迷宮中,'.'代表通路,'#'代表牆,'F'代表起火點,'J'代表Joe的位置,在每個單位時間內,火和人都可以向上下左右四個方向移動一格,注意,人和火均不能到達牆的位置,如果人能夠到達迷宮的邊界,就可以逃出迷宮,問需要的最短時間,如果不能逃生輸出-1

題解思路:BFS,題解的關鍵是先讓火災點入佇列,再讓人入佇列,火災先到達的點,人不能到達,火災能夠蔓延到人的位置,

如果人能到達邊界則返回需要的時間,否則返回-1。程式為節省空間,可以使火災到達的點置為'#',具體看程式碼

AC的C++程式:

#include<iostream>
#include<queue>
#include<cstring>

using namespace std;
const int N=1005;
//方向 
struct DIR{
	int x,y;
}d[4]={{-1,0},{1,0},{0,-1},{0,1}};

struct Node{
	int x,y,t;
	char c;//c='F'表示火 c='J'表示人 
	Node(int x,int y,int t,char c):x(x),y(y),t(t),c(c){}
};

int R,C;
queue<Node>q;
char g[N][N];

int bfs()
{
	while(!q.empty()){
		Node f=q.front();
		q.pop();
		if(f.c=='J'&&(f.x==1||f.x==R||f.y==1||f.y==C))//逃出火場,返回步數 
		  return f.t;
		for(int i=0;i<4;i++){
			int fx=f.x+d[i].x;
			int fy=f.y+d[i].y;
			if(1<=fx&&fx<=R&&1<=fy&&fy<=C&&g[fx][fy]=='.'||(f.c=='F'&&g[fx][fy]=='J')){
				if(g[fx][fy]=='.')
				  g[fx][fy]='#';
				q.push(Node(fx,fy,f.t+1,f.c)); 
			}
		}
	} 
	return -1;//返回-1表示不能逃出火場 
}

int main()
{
	int t,x,y;
	scanf("%d",&t);
	while(t--){
		//清空佇列 
		while(!q.empty())
		  q.pop();
		scanf("%d%d",&R,&C);
		//先壓入'F'再壓入'J' 
		for(int i=1;i<=R;i++)
		  for(int j=1;j<=C;j++){
		  	scanf(" %c",&g[i][j]); 
		  	if(g[i][j]=='J'){
		  		x=i;
		  		y=j;
			  }
		  	else if(g[i][j]=='F'){
				g[i][j]='#';
				q.push(Node(i,j,1,'F'));
			  }
		  }
		q.push(Node(x,y,1,'J'));//壓入J 
		int ans=bfs();
		if(ans==-1)
		  printf("IMPOSSIBLE\n");
		else
		  printf("%d\n",ans);
	}
	return 0;
}