ナイトメア(双方向BFS)

N * Mは、マップは男の子、女の子と2人の幽霊を持って、マップを与えられました。

キャラクターが道路を表し、文字は 『X』の壁を表し、文字 『M』は、少年の位置を示し、文字 『G』は、女の子の位置を表す「」、文字 『Z』は、ゴーストの位置を示しています。

少年は単位距離あたりの3を移動させることができ、毎秒女の子は男の子と女の子は、わずか4つの方向に移動することができ、単位距離を移動することができます。

各ゴーストは、単位距離2〜4週間ごとに占有面積を拡大し、マンハッタン距離は、2kの位置を超えていないすべてのゴーストゴーストを占有するの後のk秒での隔壁、すなわちを無視することができます。

注意:毎秒ゴーストは最初、拡大男の子と移動することができます女の子の完了後に拡大していきます。

占領地のゴーストを入力するように求めずに、男の子と女の子が参加することができ、我々は満たしていれば、満たすために最短時間を見つけます。

入力形式

最初の行がT、Tは、テストケースの全セットを表す整数を含んでいます。

各テストケースの最初の行は、二つの整数NおよびMが含まれているマップのサイズを表します。

マップ全体の状態を記述するために使用されるM個の文字の次のNライン。(注意:マップは、唯一の男の子、一人の女の子と2人の幽霊を持っている必要があります)

出力フォーマット

各テスト出力整数Sは、最短の収束時間を表します。

あなたは出力に参加できない場合は-1。

各結果行。


emmmmm、一度にテストプログラムが戻ってクラスに行き、その後、この事で私のコードを見に戻ってくると呼ばれます:

 

 あなたのアルゴリズム高度、孟神、ああああああ私は本当にああ取得できませんでした。
話題に-

いくつかの手順を探している、BFSを考えるのは簡単ですが、人々は別の場所に人を検索合法的な状態、の検索でポイントを訪問しながら、これは、二人が、実際には、非常に簡単で、双方向BFSを考える2つのキューを作成することですこの時のステップ数は、ステップの最小数である場合、。

#include <ビット/ STDC ++ H> 使用して名前空間STDを、
typedefの長い長いLL。
const int型 INF = 0x3f3f3f3f const int型 MAXN = 5E5 + 100 const int型 MAXM = 3E3 + 10 
テンプレート <型名T>インラインボイドリード(T&X){ 
    X = 0T FF = 1、CH = GETCHAR()。
    しばらく(!isdigit(CH)){
         場合(CH == ' - ')FF = -

 
    
1 ; 
        CH = GETCHAR()。
    } 
    一方(isdigit(CH)){ 
        X =(X << 1)+(X << 3)+(CH ^ 48 )。
        CH = GETCHAR()。
    } 
    、X * = FF。
} 

テンプレート <型名T>インラインボイドライト(T x)から{
     場合(X < 0)のputchar(' - ')、X = - X。
    もし(X> 9)書き込み(X / 10 )。
    putchar(X10 + ' 0 ' ); 
} 

int型T、N-、M;
 int型VIS [MAXM] [MAXM];
 int型の DXの【を5。 = {] 10、 - 10 };
 int型のDy [ 5 ] = { 010、 - 1 };
 CHAR CH [MAXM] [MAXM];   
ペア < int型int型 >男の子、女の子、ゴースト[ 2 ]; 

// あなたではありません神梁私の高度なアルゴリズムを- MSM 

インラインBOOLチェック(INT XX、INT YY、INT DIS){
     場合(XX < 0 || XX> = N || YY < 0 || YY> = M || CH [XX] [YY] == ' X 'リターン ;
    以下のためにint型 i = 0 ; iは< 2 ; ++ I){
         場合(ABS(XX -ゴースト[i]が1次回)+ ABS(YY -ゴーストは[i]は.second)<= 2 * DIS)を返す 
    } 
    を返す 
} 

インラインINT BFS(){
    memsetの(VIS、 j)は{0はsizeof (VIS))。
    キュー <ペア< int型int型 >> QB、QG。
    qb.push(男の子)。
    qg.push(女の子)。
    INT DIS = 0 ;
    しばらく(!!qb.empty()|| qg.empty()){
         ++ DIS;
        以下のためにint型 = Iを0 ; iは< 3 ; ++ I){
             int型 LEN = qb.size()。
            以下のためのint型 J = 0 ; jの<LEN; ++ 
                ペア < int型int型 > X; 
                X = qb.front()。
                qb.pop(); 
                int型 = x.first、B = x.secondを。
                もし((チェック、B、DIS)!)続けますint型のk = 0 ; K < 4 ; ++ K){
                     int型、U = A + DX [K]、V = B + DY [K]。
                    もし(チェック(U、V、DIS)){
                         場合(VIS [U] [V] == 2リターンDIS;
                        もし(!VIS [U] [V]){ 
                            VIS [U] [V] = 1 
                            qb.push({U、V})。
                        } 
                    } 
                } 
            } 
        } 
        int型 LEN = qg.size()。 
        以下のためにint型 iは= 0 ; iがLEN <++ {I) < INTINT > X。
            X = qg.front()。
            qg.pop(); 
            int型、A = x.first、B = x.secondを。 
            もし((チェック、B、DIS)!)続けますint型のk = 0 ; K < 4 ; ++ K){ 
                 int型、U = A + DX [K]、V = B + DY [K]。 
                もし(チェック(U、V、DIS)){
                     場合(VIS [U]は[V] == 1を返すDISと、
                    もし(!VIS [U] [V]){ 
                        VIS [U] [V] = 2 
                        qg.push({U、V})。
                    } 
                }
            } 
        } 
        
    }
    リターン - 1 
} 

int型のmain(){ 
    (T)を読み出します。
    ながら(T--は){ 
        (n)を読み出します。(m)を読み出します。
        以下のためにint型 i = 0 ; iがn <; ++ I){ 
            scanf関数(" %sの" 、CH [I])。
        } 
        INT TOT = 0 以下のためにint型私= 0 ; iがN <; ++ i)が{
             ためINT J = 0 ; J <M; ++J){
                 場合(CH [I] [J] == ' M ')少年= {I、J}。
                そう であれば(CH [I] [J] == ' G ')女の子= {I、J}。
                そう であれば(CH [I] [J] == ' Z ')ゴースト[TOT ++] = {I、J}。
            } 
        } 
        書き込み(BFS())。
        プット("" ); 
    } 
    戻り 0 
}

 

おすすめ

転載: www.cnblogs.com/AK-ls/p/11447289.html