影響を受ける:(N、M)に到達することができない(1,1)ように既に障害マップ上に、ルートビットダウン、右、いくつかの障害物として設定します。
データ範囲:N * M <= 1E6
問題解決のアイデア:それは直接(1,2)または(2,1)を妨げることができるので答えは、2以下でなければなりません。最初は、格子相同期番号が唯一のものである場合には(N、M)に到達できないように、それだけでこのグリッドを妨げることができ、全体の検索を開始するために、(1,1)から、自分の間違いの考えです。しかし、ゲームの5分の終わりに問題が見つかりました:可能ボックス「(N、M)に達するまで数と同期している」だけですが、このステップは別の番号の存在に対応してもよい(n、m)は、グリッドに到達できない答えを混乱させる。だから、解決策は、問題の解決策があるだろう:(n、m)は深い探索が始まった、(n、m)がグリッドに到達することができるだけマークで始まり、その後、私は問題を解決することができ、間違った考えを持っていました。
深い検索優先順位が右よりも大きく、他は次のより高い優先権を深く検索である、2件の深い検索を指示し、はるかに単純なアイデアがあり、試合後のコメントを参照してください。2つのパスが互いに素であるこのよう場合、回答は、回答が1である、2つのパスが交差あり、2です。このソリューションの私の理解では、以下のとおりです。前者は深い検索はさまざまなプログラムがあり、その後交わらない2つの境界の右上の境界線を描いているかもしれない深い検索した後、境界線を座るかもしれません示しています。
問題解決コード:
する#include <stdio.hの> INT NUM [ 1000010 ]。 INTのステップ[ 1000010 ]。 int型のmmap [ 1000010 ]。 int型の _MAP [ 1000010 ]。 INTの QUEの[ 1000010 ] [ 2 ]。 INTのN、M。 INTスアン(int型のx、int型Y) { 場合(X> N || Y> M || X < 1つの || Y < 1)戻り0 ; リターン(X- 1)* M + Y。 } 無効フィン( int型のx、int型のY) { MMAP [スアン(X、Y)] = 1 。 もし(_MAP [スアン(X- 1!、Y)] && MMAP [スアン(X- 1、Y)])、フィン(X- 1 、Y)。 もし(_MAP [スアン(X、Y- 1)] && MMAP [スアン(X、Y!1)])フィン(X、Y- 1 )。 } int型のmain() { scanf関数(" %D%dの"、&N、&M)。int型 mmstep = 0 ; 以下のために(int型 i = 1 ; iが<= N; iは++ ) のために(INTの J = 1 ; J <= Mであり、j ++ ) { 工程[スアン(I、J)] = 0 ; チャー CH = GETCHAR()。 しばらく(CH =!' ' && CH =!' #')CH = getchar関数(); もし(CH == ' ')_MAP [スアン(I、J)] = 1 。 他 _MAP [スアン(I、J)] = 0 ; } フィン(N、M); もし(!MMAP [スアン(1、1)]){のprintf(" 0 \ nは "); 戻り 0 ;} int型 TT = 1、LL = 0 ; QUE [LL] [ 0 ] = 1 ; QUE [LL]が[ 1 ] = 1 ; 一方(LL < TT) { int型 X = QUE [LL] [ 0 ]、yは= QUE [LL] [ 1 ]; int型 nowtp =ステップ[スアン(X、Y)]; NUM [nowtp] ++ ; もし(nowtp> mmstep)mmstep = nowtp; INT TMP =スアン(X + 1 、y)は、 もし(!X <N && MMAP [TMP] &&(ステップ[TMP])) { QUE [TT] [0 ] = X + 1 。 QUE [TT] [ 1 ] = Y。 ステップ[スアン(X + 1、Y)= nowtp + 1 。 // のprintf( "%D%D \ n"は、X + 1、Y)。 TT ++ ; } TMP =スアン(X、Y + 1 )。 もし(!Y <M && MMAP [TMP] && ステップ[TMP]) { QUE [TT] [ 0 ] =のX。 QUE [TT] [ 1 ] = Y + 1 。 ステップ[スアン(X、Y + 1)] = nowtp + 1; // のprintf( "%D%D \ n"は、X、Y + 1)。 TT ++ ; } LL ++ 。 } INT ANS = 2 。 もし(M- mmstep = N +!2 ) ANS = 0 。 以下のために(int型 i = 1 ; iはmmstepを<; I ++の) 場合(NUM [I] < ANS) ANS = NUM [I]。 printf(" %d個の\ n " 、ANS)。 }
する#include <stdio.hの> 整数N、M。 ブールフラグ[ 1000100 ]。 BOOL TMP = 0、TMP2 = 0 。 INT GET(int型のx、int型のY) { 場合(X> N || Y> M)戻り 0 ; リターン(X- 1)* M + Y。 } BOOL FIN1(int型のx、int型のY) { フラグ[ 取得(X、Y)= 0 。 もし(x == N && Y == mの){TMP = 真。リターン 0 ;} もし(!TMP &&フラグ[ 取得(X + 1、Y)])FIN1(X + 1 、Y)。 もし(!TMP &&フラグ[ 取得の(x、y + 1)])FIN1(X、Y + 1 )。 } BOOL FIN2(int型のx、int型のY) { フラグ[ 取得(X、Y)= 0 。 もし(x == N && Y == mの){TMP2 = 真。戻り 0 ;} もし(TMP2 &&フラグ[!得る(X、Y + 1 FIN2(X、Y +)])1 )。 もし(!TMP2 &&フラグ[ 取得(X + 1、Y)])FIN2(X + 1 、Y)。 } int型のmain() { scanf関数(" %D%dの"、&N、&M)。 以下のために(int型 iは= 1は I ++; iがn = < ) のための(INT J = 1 ; J <= Mであり、j ++ ) { チャー CH = GETCHAR()。 しばらく(CH =!' ' && CH =!' #')CH = getchar関数(); もし ==(CH" 。')フラグ[ 取得(I、J)] = 真。 他のフラグは、[ 取得(i、j)は= 偽; } FIN1(1、1 )。 もし(!TMP){ のprintf(" 0 \ N "); リターン 0 ; } フラグが[ 1 ] = 真、フラグ[ 取得(N、M)は= 真。 FIN2(1、1 )。 もし(TMP2){ のprintf(" 2 " )。 } 他 のprintf(" 1 " )。 }