タイトル説明
斜めn行m列与えられ、(0,0)からの要求は、他過ごす、斜め方向は0をとる場合に行き、ダウンわずか4斜め方向に、(n、m)は同じ方向に来ます1。
考え
BFSより古典的なタイトル、0,1最短アドレス両端キューとして見ることができます。両端キューは、単調に増加する(しかし厳密に増加していない)されているキューの先頭に尾部から、すなわちキューの場合、特定の要素、ステップ、単調性のキューを維持するために使用されます。しかし、この質問には注意が必要ないくつかの詳細があります。
まず、あなたが適切に道路や参照するには明確な必要性を行くためのポイントとの間の関係を扱うスラッシュということです。
第二に、また原因のステップに、括弧で述べた重要な点は、厳密には、単一の増加ではありませんので、我々は我々が今までできて、本に、0(2,2)に過ごすためVISは、例えば、訪問したかどうかをストレージアレイを使用していません1は、(3,1)の合計対価に来ることができるように(2,0)から、VIS配列のレコードの後、(3,1)の費用に行ってきましたが、彼らが訪問してきたので、無視されます。最小コストあなたはあまりを過ごすことができるのであれば、我々は、(x、y)にコストを最小以上に配列を格納することができます。
コード
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 構造体A-A { int型X、Y、ステップと AA(INT X = 0、INT、Y = 0、INTのステップ= 0 )、X(x)、Y(y)は、工程(ステップ){} }。 INT DX [ 4 ] = { 1、1、 - 1、 - 1 }、DY [ 4 ] = { 1、 - 1、1、 - 1 }。 INT PX [ 4 ] = { 0、0、1、1 }、PY [ 4 ] = { 0、1、0、1 }。 チャー MP [ 550 ] [ 550 ]。 ブールチェック(int型のx、int型の Y、INT T) { 場合(MP [X] [Y] == ' / ' ) { 場合(Tの== 0 || Tの== 3)リターン 1 。 それ以外 の戻り 0 ; } 他 { もし(T == 0 || Tの== 3)戻り 0 ; 他の リターン 1 。 } } int型のコスト[ 550 ] [ 550 ]。 INTのN、M。 BOOL有効(int型のx、int型の Y){ リターン X> = 0 && Y> = 0 && X <= N && Y <= M;} ボイド BFS(int型 SX、int型SY) { memsetの(コスト、0x3fを、はsizeof (コスト))。 両端キュー <AA>Q; q.push_front(AA(SX、SY、0 )); コスト[SX] [SY]は = 0 ; 一方、(!q.empty()) { AA U = q.front(); q.pop_front()。 もし(UX == N && u.y ==のM) { のprintf(" %dの" 、u.step)。 返します。 } のために(int型 i = 0 ; iは< 4 ; iは++ ) { int型 NX = u.x + DX [I]。 int型 NY = u.y +DY [I]; 場合(有効(NX、NY)) { BOOL F =チェック(NX + PX [I]、NY + Pyの[I]、I); // スラッシュのP配列と転写ポイントによって実装 場合(コスト[NX] [NY] <=コスト[UX] [UY] + F)続行 ; // この時点のコストとの比較は、等号のある コスト[NX] [NY] =コスト[UX] [UY] + F; IF(F)q.push_back(AA(NX、NY、u.step + 1。 )); // キューの両端キュー吐出ヘッド、テール 他のq.push_front(AA(NX、NY、u.step)) ; } } } のprintf(" NO SOLUTION " ); } int型のmain() { scanf関数(" %d個の%のD "、&N、&M)。 用(int型 iは= 1 ; iが<= N iが++ ) のscanf(" %sの"、MP [I] + 1 )。 BFS(0、0 ); }