迷路(幅優先アルゴリズム)

件名の説明:

説明

N * Mラビリンスグリッドを有し、グリッドは、壁の代表である、添加による0を表すことができない、迷路の中で
いくつかのポータル、すなわち、入口ポータルに移動し、自動的に出口ポータルに転送されます(一次転写カウントステップ1)。迷路の人々がしようとすることができます
上下4つの方向に移動します。迷路と今すべてのポータル入り口だけでなく、開始点と終了点を考えると、
少なくとも迷路のうち、どのように多くのステップをすることができます尋ねます。それは迷路出力の外にされていない場合、「死にます」。

入力形式

マルチ場合のプログラムの最初のケースの挙動の数
CASEのそれぞれ、最初の2点の数N(行)とM(列)の挙動
及びMのN行の数
数W続いて、転送ゲートの数
各行の後エントリのポータルは、C1(ライン)、R1(列)の座標および出口C2を調整し、R2
に続く開始点と終了点SC(OK)SR(カラム)EC(OK)ER(カラム)

注意:ポータルの入り口と、開始点と終了点を壁の場所に表示されていない
すべての数値が100を超えていません

出力フォーマット
タイトルなど

サンプル入力

2
4 3
011
011
110
110
1
1 0 2 2
0 0 3 2
2 2
01
10
0
0 0 1 1

サンプル出力

3

タイトルのアイデアを実行します。

複数の2次元配列を作成し、それぞれのマップ、入口と出口、入り口を保持し、ポータルを終了し、あなたが最後に到達するかどうかを判断するためのフラグ変数を設定する必要があります

幅優先トラバーサルシミュレーション迷路状態を利用することができ、それは散歩の出発点から離れて、マップ内のいくつかの手順を、現在位置の座標を保存するための構造が必要になります。

メイズ手術では、「1」ではなく、その横の格子、グリッドの座標のエントリのポータルは、トランスファゲートの現在の状態は、位置座標出口、およびステップ数プラス1に調整する必要がある。ためグリッドの終点として、フラグ変数の最後に到達するように設定され、ケースを終了します

注意することはポイントが必要になります。

  1. マルチケース
  2. グリッドへ歩いたが「1」に設定されています
  3. 開始点と終了点は、ケースを一致

幅優先トラバーサルアルゴリズムを理解するために

それに基づいて、私はスパイダーと比較したいと思いますので、実施例で導入幅優先トラバーサルと迷路の周りにスライドのように、水の波紋のように理解することができるが、ノードとノードとの間の関係を反映しにくいですネットワーク、物体が衝突物体のクモの巣、位置(初期ノード)に当たるとき、スパイダーの衝撃力は、初期ノードを有して接続されているが、次のノードに送信され、この手順を繰り返し、そしてはありませんバックに。すなわち、幅を横断しているときに、周りとしない節点に関連付けられることは、第一トラバースするためにトラバースし、すべてのノードがトラバースされるまでこの手順を繰り返します。ノードが複数のノードに関連付けられており、トラバースすることはできませんので、我々はこのキュー「同時」トラバーサルをシミュレートすることができます。

具体的な例:

  1. トラバースの周囲四方に発見される、出発点に横切ります

  2. キューの状態が4つの方向に押し込まれます

  3. トラバーサル開始

  4. 反復の開始点は、開始点のトラバーサル方向上の点の最初の点完了し、その関連するキューが押下され、​​関連する第一の方向に配列されたドットの組がそうでT1、T2で第であり、そして。

    現在のキュー:第二方向、第3方向出発点、第4の方向の始点、Tlの出発

  5. キューの状態になるまで4サイクルステップ:

    第4の方向、T1、T2、T3を開始

  6. 出発第4の方向の点とキューから排出され、この場合にトラバースされるときに、四方の「同時」トラバース開始シミュレーションを完了するためにキュー。

(コメントを含む)コード

#include <iostream>
#include <cstdio>
#include <malloc.h>
#include <queue>
using namespace std;
int d[4][2]={{-1,0},{0,1},{1,0},{0,-1}}; //四个方向
char s[110][110];       //地图大小
int sr,sc;      //初始地点
int er,ec;      //目标地点
int In[110][2],Out[110][2]; //传送门入口和出口坐标

typedef struct{
int row;
int col;        //位置
int step;       //步数
}node;      //每次走的记录


int main()
{
    int k;
    scanf("%d",&k); //多case
    while(k--)
    {
        int m,n,flag=0,jump=0;
        scanf("%d%d",&m,&n);        //行列数
        int i;
        for(i=0;i<m;i++)
        {
            scanf("%s",s[i]);       //每行迷宫
        }
        int num;
        scanf("%d",&num);       //传送门数量
        for(i=0;i<num;i++)
        {
            scanf("%d%d%d%d",&In[i][0],&In[i][1],&Out[i][0],&Out[i][1]);        //传送门入口坐标和出口坐标
        }
        scanf("%d%d%d%d",&sr,&sc,&er,&ec);      //起点和终点坐标

         node first;
         first.row=sr;
         first.col=sc;
         first.step=0;      //设置起点node

         queue <node> Q;
         Q.push(first);

         while(!Q.empty())
         {
             node cur;
             cur=Q.front();
             Q.pop();
             jump=0;

             if(cur.row==er&&cur.col==ec)   //是否是终点
             {
                 printf("%d\n",cur.step);
                 flag=1;        //已到达终点标志
                 break;
             }

             for(i=0;i<num;i++)     //检测是不是传送门位置
             {
                 if(cur.row==In[i][0]&&cur.col==In[i][1])
                 {
                     node newnode;
                     newnode.row=Out[i][0];
                     newnode.col=Out[i][1];         //传送后的坐标
                     newnode.step=cur.step+1;       //步数+1
                     Q.push(newnode);       //推入该坐标
                     jump=1;        //传送门使用标志
                     break;

                 }
             }
             if(!jump)      //未使用传送门
             {

                 for(i=0;i<4;i++)       //四个方向
                 {
                     int k=0;
                     node now;
                     now.row=cur.row+d[i][0];
                     now.col=cur.col+d[i][1];
                     now.step=cur.step+1;       //步数+1
                     if(now.row<0||now.row>=m||now.col<0||now.col>=n)  continue; //边界检测
                     if(s[now.row][now.col]=='0')
                     {
                         s[now.row][now.col]='1';   //走过的标志位
                         Q.push(now);
                     }
                 }
             }

         }//while
            if(!flag)  //flag未设置成终点标志,die
            {
                printf("die\n");
            }
    }//while
}

おすすめ

転載: www.cnblogs.com/Dozeer/p/10961769.html