1. 程式人生 > >NEFU 1214 逃出迷宮 (BFS尋徑)

NEFU 1214 逃出迷宮 (BFS尋徑)

題意:

中文

思路:
兩種思路:
1》火先走完人再走——先BFS火堆,將圖染色,標記到某一點的時間,再BFS人的行走路徑。

2》火和人一起走——同時BFS火和人

程式碼:(只給出思路2)

#include <iostream>
#include <queue>
#include <cstdio>
using namespace std;
typedef struct Node{
    int x;int y;int step;
    Node(int xx=0,int yy=0,int ss=0){
        x=xx;y=yy;step=ss;
    }
}Node;
const int MAXN=1e4;
char a[MAXN][MAXN];
int n,m,now,ans,Mp[MAXN][MAXN];
queue <Node> fir;
queue <Node> mov;
int dir_x[4]={0,1,-1,0};
int dir_y[4]={1,0,0,-1};
void burn(){
    Node t;
    int x,y;
    while(!fir.empty()){
        t=fir.front();
        if(t.step>now) break;
        fir.pop();
        for(int i=0;i<4;i++){
            x=t.x+dir_x[i];
            y=t.y+dir_y[i];
            if(x<1||x>n||y<1||y>m) continue;
            if(Mp[x][y]==0||Mp[x][y]==1){
                fir.push(Node(x,y,t.step+1));
                Mp[x][y]=-1;
            }
        }
    }
    return ;
}
int move(){
    Node t;
    int x,y;
    while(!mov.empty()){
        t=mov.front();
        if(t.step>now) return 0;
        mov.pop();
        for(int i=0;i<4;i++){
            x=t.x+dir_x[i];
            y=t.y+dir_y[i];
            if(x<1||x>n||y<1||y>m) return 1;
            if(Mp[x][y]==0){
                mov.push(Node(x,y,t.step+1));
                Mp[x][y]=1;
            }
        }
    }
    return -1;
}
void solve(){
    now=1;
    while(1){
        burn();

        int res=move();
        if(res==-1){
            ans=0;
            break;
        }else if(res==0){
            now++;
            continue;
        }else if(res==1){
            ans=now;
            break;
        }
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d %d",&n,&m);
        getchar();
        while(!fir.empty()) fir.pop();
        while(!mov.empty()) mov.pop();
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                scanf("%c",&a[i][j]);
                if(a[i][j]=='J'){
                    Mp[i][j]=0;
                    mov.push(Node(i,j,1));
                }else if(a[i][j]=='.'){
                    Mp[i][j]=0;
                }else if(a[i][j]=='#'){
                    Mp[i][j]=-1;
                }else{
                    Mp[i][j]=-2;
                    fir.push(Node(i,j,1));
                }
            }
            getchar();
        }
        solve();
        if(ans){
            printf("%d\n",ans);
        }else{
            puts("IMPOSSIBLE");
        }
    }
}

Description


你的任務是幫助小明逃出迷宮,迷宮中有一個小明的位置,有障礙(不確定個數,障礙不允許人和火堆蔓延),有空地(不確定個數),有火堆(不確定個數),
小明每分鐘可以走上下左右四個位置,火堆每分鐘可以向旁邊的空地蔓延,當小明走出迷宮的邊界格子則代表小明逃出迷宮如果小明不可能走出迷宮,則輸出IMPOSSIBLE,
否者輸出逃出迷宮的最少時間(分鐘)

Input


輸入組數T,每組有R和C,代表R行C列,然後‘#’代表障礙,‘.’代表空地,‘J’代表小明(保證只有一個),‘F’代表火堆

Output


走不出去輸出IMPOSSIBLE,否者輸出最少時間

Sample Input


2
4 4
####
#JF#
#..#
#..#
3 3
###
#J.
#.F

Sample Output


3
IMPOSSIBLE