您的位置:首页 > 其它

UVA 11624 Fire! (技巧BFS)

2018-01-20 19:27 447 查看
题意:一个地图中有空地有墙,空地可以走。地图中有两中物品,一种是人,每分钟可以上下左右任走一格,一种是火,每分钟会向上下左右一起扩散。问人是否可以逃脱迷宫。逃脱迷宫的条件是到达边缘。

题解:我的思路比较奇特,我把火和人放在一个队列中处理了。这种处理方式是先处理火,然后再处理人。为什么这样是对的呢如下图:



就是队列中一定是一段人,然后一段火,这样保证人和火是同事进行的。单必须先把火比人先放进队列中,这样才能保证人不会走到火将要烧到的位置。如下图



若人先走的火,人会向左走,但是火也会向右走,意味着火和人会走到一个格子里。这是会烧死人的。

具体代码细节看注释。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
const int maxn = 1010;
char map[maxn][maxn]; // 地图
int book[maxn][maxn]; // 标记数组,记录这点火或者人是否走过

struct node{
int x; //坐标x
int y; // 坐标y
int step; // 人的步数
int kind; // 用来区分是人还是火,1是人,0是火
};
queue<node> q;
int n,m,ans; // n,m表示长宽。ans表示火的个数
node ren; //记录人的起始位置
node fire[maxn]; // 记录火的起始位置
int mov[4][2] = {1,0,-1,0,0,1,0,-1}; // 移动数组
void bfs(){
node now,next;
for(int i = 0 ; i < ans ; i++){ // 先把火入队列
q.push(fire[i]);
}
q.push(ren); // 再把人放入队列
// cout<<ren.step<<endl;
while(!q.empty()){
now = q.front();
q.pop();
if(now.kind == 1 && (now.x == 0 || now.y== 0 || now.x == n-1 ||now.y == m-1)){ // 当是人到达边缘时
cout << now.step+1 << endl;
return ;
}
for(int i = 0 ; i < 4 ; i++){ // 对火对人进行移动
next.x = now.x+mov[i][0];
next.y = now.y+mov[i][1];
if(next.x < 0 || next.x >= n || next.y < 0 || next.y >= m || book[next.x][next.y] == 1 || map[next.x][next.y] == '#')//判断是否可走和越界
continue;
next.kind = now.kind; // 记录种类
book[next.x][next.y] = 1; // 标记已走
// printf("%d %d %d\n",next.x,next.y,next.step);
if(now.kind) // 若为人 顺带记录步数
next.step = now.step + 1;
q.push(next); //入队列
}
}
cout << "IMPOSSIBLE" << endl;
}
int main(){
int z;
cin >> z;
while(z--){
while(!q.empty()) q.pop(); // 清空很重要
memset(map,0,sizeof(map));
memset(book,0,sizeof(book));
ans = 0;
cin >> n >> m;
for(int i = 0 ; i < n ; i++)
cin >> map[i]; // 输入地图信息
for(int i = 0 ; i < n ; i++){
for(int j = 0 ; j < m ; j++){
if(map[i][j] == 'J'){ // 查找人的起始位置
ren.x = i;
ren.y = j;
ren.step = 0;
ren.kind = 1;
}
if(map[i][j] == 'F'){ // 查找所有火的起始位置
fire[ans].x = i;
fire[ans].y = j;
fire[ans].kind = 0;
fire[ans].step = 0;
ans ++;
book[i][j]=1;
}
}
}
bfs();
}
return 0;
}
/*
2
4 4
####
#JF#
#..#
#..#
3 3
###
#J.
#.F
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: