又到了开始练习ACM的季节了。不知道这次会坚持多久。但是希望自己好好坚持吧,自己选的路要对自己负责。
UVA 11624FIRE
给出题目链接,题意大致是一张地图,有障碍,有几堆火焰会随着时间蔓延开来,Joe以同样的速度移动,问题就是Joe能不能安全跑出图外。
思路就是两遍bfs,第一遍先把所有的火焰都加入队列,bfs出各个点最早被火焰覆盖的时间;第二遍再简单地bfs人的步数,在火烧到之前能到达的格子。
自己写的代码里的一些bug:一开始就在边界的情况;火被墙挡了根本烧不到的情况。就这样。
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
#define maxN 1001
typedef struct Point{
int x,y;
Point(int xx=0,int yy =0): x(xx),y(yy){}
} point;
int r,c;
char map[maxN][maxN];
int f[maxN][maxN],fj[maxN][maxN];
point joe;
struct Queue{
point que[maxN*maxN];
int head,tail;
void clear(){
head=0;
tail=0;
}
void append(int x, int y){
tail++;
que[tail].x=x;
que[tail].y=y;
}
point pop(){
return que[head];
}
} q;
int dir[8]={0,1,0,-1,1,0,-1,0};
void bfs_fire(){
while (q.head<q.tail){
q.head++;
point cur = q.pop();
int xx,yy,ff;
for (int i = 0; i<=3; ++i){
xx=cur.x+dir[i];
yy=cur.y+dir[i+4];
ff=f[cur.x][cur.y];
if (xx>0 && xx<=r && yy>0 && yy<=c && map[xx][yy]!='#' && f[xx][yy]==0){
q.append(xx,yy);
f[xx][yy]=ff+1;
}
}
}
}
int bfs(){
while (q.head<q.tail){
q.head++;
point cur = q.pop();
int xx,yy,ff;
for (int i = 0; i<=3; ++i){
xx=cur.x+dir[i];
yy=cur.y+dir[i+4];
ff=fj[cur.x][cur.y];
if (xx>0 && xx<=r && yy>0 && yy<=c && map[xx][yy]!='#' && (f[xx][yy]>ff+1 || f[xx][yy]==0) && fj[xx][yy]==0){
if (xx==1 || yy==1 || xx==r || yy==c) {
return ff+1;
}
q.append(xx,yy);
fj[xx][yy]=ff+1;
}
}
}
return 0;
}
int main(){
int test;
char ch;
cin >> test;
while (test--){
cin >>r >> c;
scanf("%c",&ch);
q.clear();
for (int i=1; i<=r; ++i ){
for (int j=1; j<=c; ++j){
scanf("%c",&map[i][j]);
f[i][j]=0;
fj[i][j]=0;
if (map[i][j]=='F') {
q.append(i,j);
f[i][j]=1;
}
else if (map[i][j]=='J'){
joe.x=i;
joe.y=j;
fj[i][j]=1;
}
}
scanf("%c",&ch);
}
if (joe.x==1 || joe.y==1 || joe.x==r || joe.y==c) {
cout<<1<<endl;
continue;
}
bfs_fire();
for (int i=1; i<=r; ++i) {
for (int j=1; j<=c; ++j){
cout<<f[i][j];
}
cout << endl;
}
q.clear();
q.append(joe.x,joe.y);
int ans = bfs();
if (ans==0) {
cout<<"IMPOSSIBLE"<<endl;
}
else cout<<ans<<endl;
}
}