Barareh on Fire

Barareh on Fire

题目描述

The Barareh village is on fire due to the attack of the virtual enemy. Several places are already on fire and the fire is  spreading fast to other places. Khorzookhan who is the only person remaining alive in the war with the virtual enemy, tries to rescue himself by reaching to the only helicopter in the Barareh villiage.
Suppose the Barareh village is represented by an n m grid. At the initial time, some grid cells are on fire. If a cell catches  fire at time x, all its 8 vertex-neighboring cells will catch fire at time x + k. If a cell catches fire, it will be on fire forever.
At the initial time, Khorzookhan stands at cell s and the helicopter is located at cell t. At any time x, Khorzookhan can  move from its current cell to one of four edge-neighboring cells, located at the left, right, top, or bottom of its current cell  if that cell is not on fire at time x + 1. Note that each move takes one second.
Your task is to write a program to find the shortest path from s to t avoiding fire.

输入

There are multiple test cases in the input. The first line of each test case contains three positive integers n, m and k  (1 ⩽ n, m, k ⩽ 100), where n and m indicate the size of the test case grid n m, and k denotes the growth rate of  fire. The next n lines, each contains a string of length m, where the jth character of the ith line represents the cell (i, j)  of the grid. Cells which are on fire at time 0, are presented by character “f”. There may exist no “f” in the test case. 
The helicopter and Khorzookhan are located at cells presented by “t” and “s”, respectively. Other cells are filled by “-”  characters. The input terminates with a line containing “0 0 0” which should not be processed.

输出

For each test case, output a line containing the shortest time to reach t from s avoiding fire. If it is impossible to reach t  from s, write “Impossible” in the output.

样例输入

7 7 2
f------
-f---f-
----f--
-------
------f
---s---
t----f-
3 4 1
t--f
--s-
----
2 2 1
st
f-
2 2 2
st
f-
0 0 0

样例输出

4
Impossible
Impossible
1
题目大意:给你一个n*m的方格,f代表火,s代表人的起始位置,t代表人要到达的位置,每把火每k个时间会使它周围的8个方格都变成火,火先蔓延,人再走,有火的方格人
不能走,问是否存在可以使人到达t路径走法。
解题思路:两次BFS,因为每k个时间火比人先走,所以第一次先对火进行一次bfs,来记录火的行走路径。第二次对人走的路径进行BFS,来记录人的行走路径。在对人的bfs过程
中,同时判断火的位置。
给出的c++代码:
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
#define inf 0x3f3f3f3f
typedef struct nodee{
	int x,y;
}node; 
int tre[8][2]={-1,0,-1,1,0,1,1,1, 1,0 ,1,-1 ,0,-1 ,-1,-1};
int vis[1010][1010],maze[1010][1010],n,m; 
int str[4][2]={-1,0,1,0,0,-1,0,1};
char a[1010][1010]={'\0'};
int main(){
  	int i,j,k,u,v,uu,vv,xx,yy;
	node now;
	queue<node> q;
	
	while(scanf("%d %d %d",&n,&m,&k)!=EOF){ 	
		if(n==0&&m==0&&k==0)
			 break;
			 
		for(i=0;i<n;i++){
			getchar();
			scanf("%s",a[i]); 
		}
			
		for(i=0;i<n;i++){ 	
			for(j=0;j<m;j++){ 	
				vis[i][j]=inf; 
			    maze[i][j]=inf; 
				if(a[i][j]=='f'){ 
					maze[i][j]=0; 
					now.x=i; 
					now.y=j; 		 	 
					q.push(now); 			 
				} 			 
				else if(a[i][j]=='s'){ 			 	 
					vis[i][j]=0; 			 	 
					u=i; 			 	 
					v=j; 		 
				} 			 
				else if(a[i][j]=='t'){ 			 	 
					uu=i; 			 	 
					vv=j; 			 
				} 	
			} 		
		} 		
			
	 	while(!q.empty()){
 			now=q.front();
			q.pop();  			
			for(i=0;i<8;i++){ 				
				xx=now.x+tre[i][0]; 				
				yy=now.y+tre[i][1]; 			
				if(yy>=0&&yy<m&&xx>=0&&xx<n){ 				
					if(maze[xx][yy]-maze[now.x][now.y]>k){		
						 maze[xx][yy]=maze[now.x][now.y]+k;
						 node no;
						 no.x=xx; no.y=yy; 					
						 q.push(no);	 				
					}
 				} 	
			}
 		}            //对火的BFS
 		
	 	now.x=u;
	 	now.y=v;
	 	q.push(now);
	 	
 		while(!q.empty()){ 	
			now=q.front(); 	
			q.pop();
			
			for(i=0;i<4;i++){ 	
				xx=now.x+str[i][0]; 
				yy=now.y+str[i][1];	
				if(xx>=0&&xx<n&&yy>=0&&yy<m){
	 			 	if(vis[now.x][now.y]+1>=maze[xx][yy])
					   continue; 			 
					if(vis[now.x][now.y]+1<vis[xx][yy]){
				 		vis[xx][yy]=vis[now.x][now.y]+1;
						node no;
						no.x=xx; no.y=yy; 			 	
						q.push(no); 			
						}
	 				} 
				} 
			} 		
			      //对人的bfs
		if(vis[uu][vv]==inf) 
			printf("Impossible\n"); 
		else 
			printf("%d\n",vis[uu][vv]); 
	}
	
 	return 0;
}

解题心得:一次bfs,爆时间,爆空间,还不容易处理,以时间为变量轴,来判断火和人的轨迹走向。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值