J - Fire![bfs.]

这道题写的我好气= =。
题意大致是,一个人,在一个迷宫里。而这个迷宫里有地方着火了,人要跑,火要追(蔓延)。
人不能越墙逃跑,不能跑到火海中,问能不能跑出迷宫。
火蔓延是四个方向,人只能跑一条路。

脑洞:本来是想,人不是要跑吗,火不是要蔓延吗? 我先让火跑,记录下每一个点火势蔓延到的时间,然后人如果要跑到那个点的话,时间一定是小于火势蔓延到那个点的时间的。所以在火的bfs过后 人再来bfs,而且加一个判断,就是人跑到那个点的时间是否小于火蔓延到那个点的时间。

然后交,然后wr。。。
后来发现火花可能不止一个,有可能有好几个火源。
然后改,交,然后wr。
最后发现还可能没有火。。。= =。
然后交过了。。。。

struct node {
    int x,y,step;
};

int T, n, m;
int vis_F[len][len], vis_J[len][len];//fire  Joe
char map[len][len];
int J_x, J_y, F_x[len], F_y[len];//用数组去存火花位置,因为可能不止一个
queue <struct node> q;
struct node head;
int p = 0;
int dv[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
int main(){
    cin >> T;
    while (T--) {
        cin >> n >> m;
        Init();
        bfs_fire();
        bfs();
        
        int ans = MAXN;
        for (int i=0; i<n; i++){
            for (int j=0; j<m; j++){
               if( (i==0 || i==n-1 || j==0 || j==m-1) && vis_J[i][j] != -1){
                    if (ans > vis_J[i][j]) ans = vis_J[i][j];
                }
            }
        }//人要跑到边沿才能出去,而且从边沿出去还要一分钟
   
     /*
        for (int i=0; i<n; i++){
            for (int j=0; j<m; j++){
                cout << vis_F[i][j] << " ";
            }
            cout << endl;
        }
        cout << endl;
        
        for (int i=0; i<n; i++){
            for (int j=0; j<m; j++){
                cout << vis_J[i][j] << " ";
            }
            cout << endl;
        }
        cout << endl;
    */
        if (ans != MAXN) cout << ans + 1 <<endl;
        else cout << "IMPOSSIBLE" << endl;
    }
    return 0;
}
void Init(){
    memset(vis_F, -1, sizeof(vis_F));
    memset(vis_J, -1, sizeof(vis_J));
    memset(map, '\0', sizeof(map));
    memset(F_x, 0, sizeof(F_x));
    memset(F_y, 0, sizeof(F_y));
    p = 0;
    
    while (!q.empty()) q.pop();
    
    read();
    struct node tmp;
    for (int i=0; i<p; i++){
        tmp.x = F_x[i]; tmp.y = F_y[i];
        tmp.step = 0;
        q.push(tmp);
    }//火花可能不止一个 全部入队
    
}
void read(){
    for (int i=0; i<n; i++){
        for (int j=0; j<m; j++){
            cin >> map[i][j];
            
            if (map[i][j] == 'F'){
                F_x[p] = i; F_y[p] = j;
                p++;
            }
            
            if (map[i][j] == 'J'){
                J_x = i; J_y = j;
            }
        }
    }
}
//套路式的两个bfs。
void bfs_fire(){
    
    for (int i=0; i<p; i++){
        vis_F[F_x[i]][F_y[i]] = 0;
    }
    
    while (!q.empty()) {
        head = q.front(); q.pop();
        
        for (int i=0; i<4; i++){
            int _x = head.x + dv[i][0];
            int _y = head.y + dv[i][1];
            
            if (_x<0 || _x>=n || _y<0 || _y>=m) continue;
            if (map[_x][_y] == '#') continue;
            if (vis_F[_x][_y] != -1) continue;
            
            
            struct node ans;
            ans.x = _x; ans.y = _y;
            ans.step = head.step + 1;
            vis_F[_x][_y] = ans.step;
            q.push(ans);
        }
    }
}

void bfs(){
    while (!q.empty()) q.pop();
    vis_J[J_x][J_y] = 0;
    
    struct node tmp;
    tmp.x = J_x; tmp.y = J_y; tmp.step = 0;
    q.push(tmp);
    
    while (!q.empty()) {
        head = q.front(); q.pop();
        
        for (int i=0; i<4; i++){
            int _x = head.x + dv[i][0];
            int _y = head.y + dv[i][1];
            
            if (_x<0 || _x>=n || _y<0 || _y>=m) continue;
            if (map[_x][_y] == '#') continue;
            if (vis_J[_x][_y] != -1) continue;
            if (vis_F[_x][_y] <= head.step+1 && vis_F[_x][_y] != -1) continue;
            
            struct node ans;
            ans.x = _x; ans.y = _y;
            ans.step = head.step + 1;
            vis_J[_x][_y] = ans.step;
            q.push(ans);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值