グラップリングフックで木々の間をスイング


8

森の中小道を見つけたので、森に沿って旅行する予定です。しかし、あなたが旅を始める直前に、地面は溶岩に変わります。

あなたはなんとか最も近い木を急いでなんとかします(どうしても木は燃えませんでした)。答えは、プログラミングの課題にぴったりだと思います。魔法のグラップリングフック(先にカヌーで作ったもの)を使って、木や枝を振り回すことができます。

ただし、そこにたどり着くためにどの木や枝を振り回す必要があるかはわかりません。幸い、あなたにはプログラミングのスキルがあるので、腕にプログラムを描き、どの木にスイングするかを教えることにしました。ただし、腕には表面積があまりないため、プログラムをできるだけ小さくする必要があります。

nby m配列を使用してフォレストを表すことができます。次の文字が配列を構成します。

  • T:木。ここに着陸できます。これにはグラップリングフックを使用できません。あなたはこれを通り抜けることができます。
  • P:と同じように機能しTます。ここから始めます。
  • Q:と同じように機能しTます。これが目標です。
  • +:ブランチ。ここに着陸することはできません。これでグラップリングフックを使用できます。あなたはこれを通り抜けることができます。
  • *:人食いクモ。ここに着陸すると死ぬ。これでグラップリングフックを使うと死ぬ。これを振り回すと死にます。
  • -:通常の地面、言い換えれば溶岩。ここに着陸することはできません。これにはグラップリングフックを使用できません。あなたはこれを通り抜けることができます。指定された配列の外側のすべての領域がこのタイプです。

以下は、森がどのように見えるかの例です。

               y
----T---+------12
---------------11
----T---+---T--10
---------------9
T-+-T-+-T------8
---------------7
------------+--6
----+----------5
+-------+------4
---------------3
----P---+-*-Q--2
---------------1
T-+-T-+-T------0
012345678911111
x         01234

(x,y)座標軸に示されているように、座標をと表記します。

あなたはから始めてP、あなたの方法を作らなければなりませんQ。これを行うには、ブランチを使用Tしてツリーからツリーにスイングします。グラップリングフックは、直交するブランチ(つまり、現在のx位置またはy位置と同じブランチ)に取り付けることができます。たとえば、サンプルのフォレストの位置にいる場合は、グラップリングフックを、、またはの位置に取り付けることができます。あなたと枝の間に木や他の枝があったとしてもこれを付けることができます。T+(4,8)(2,8)(6,8)(4,5)

グラップリングフックを枝に取り付けたら、最初の位置と枝の間の距離の2倍に等しい距離を枝の方向に移動します。言い換えると、最終位置は、ブランチから開始位置と同じ距離で、ちょうど反対側になります。運動がどのように機能するかについてのより正式な定義は以下のとおりです。の添え字vは、最終位置、u初期位置、およびb分岐の位置です。

バツvyv=2バツbバツあなた2ybyあなた

最初の位置と最後の位置の間にクモがいる場合は、そこに移動できないことに注意してください。たとえば、サンプルフォレストでは、からスパイダーにぶつかるため、から(4,2)へのスイング(12,2)はできません(10,2)

目標は、このスウィングスルーブランチ法を使用して、可能な限り少ないスイングでポイントPからポイントに移動することです。たとえば、フォレストの例では、最短パスは次のとおりです。Q

  1. 以下から(4,2)(4,8)使用(4,5)
  2. 以下から(4,8)(0,8)使用(2,8)
  3. 以下から(0,8)(0,0)使用(0,4)
  4. 以下から(0,0)(4,0)使用(2,0)
  5. 以下から(4,0)(4,10)使用(4,5)
  6. 以下から(4,10)(12,10)使用(8,10)
  7. 以下から(12,10)(12,2)使用(12,6)

入力

入力はraw_input()、変数として事前に初期化されない場合を除いて、便利なメソッド(STDIN、コマンドライン引数など)からのものです。入力開始2カンマで区切られた整数とnし、mその後、基板の大きさ、スペース、その後、単一の長い文字列としての森林を表します。たとえば、入力としてのフォレストの例は次のようになります。

15,13 ----T---+-------------------------T---+---T-----------------T-+-T-+-T---------------------------------+------+----------+-------+-------------------------P---+-*-Q-----------------T-+-T-+-T------

出力

スイングする必要があるブランチの座標を示す、コンマ区切りのタプルのスペース区切りリストを出力します。たとえば、上記の入力の場合、出力は次のようになります。

4,5 2,8 0,4 2,0 4,5 8,10 12,6

これがフォレスト内の唯一の最短経路ではないことに気づいたかもしれません-実際、そこ(8,8)から(8,0)、左、左、(4,0)そしてそこから通常どおりに続くのは、まったく同じ数のスイングです。これらの場合、プログラムはどちらの最短パスも出力する可能性があります。したがって、出力:

4,5 6,8 8,4 6,0 4,5 8,10 12,6

も許可されます。これはなので、バイト数が最も少ないエントリが優先されます。質問がある場合や私の説明がはっきりしない場合は、コメント欄で質問してください。


15,13配列のサイズは13 x 15であるため、サンプル入力が開始されます。
ハワード

@ハワード修正。ありがとうございました。
アブサン

回答:


4

GolfScript、196文字

' '/(~):H;,):W(\~/-1%'*':S*:^{:I,,{I=79>},:A{{[\1$1$+2/]}+A/}%{)I=43=\$.~I<>S&!\~+1&!&&},}:C~S^W/zip*C{{.H/\H%W*+}%}%+:B;^'P'?]]{{(B{0=1$=},\;\`{\1>\+}+/}%.{0=^=81=},:|!}do;|0=1>-1%{.W%','@W/' '}/

GolfScriptコードの恐ろしい部分-しかし、それは必要に応じて機能します。アルゴリズムは最適ではありませんが、かなり高速です。この例は私のコンピュータで1秒未満で実行されています。

> 15,13 ----T---+-------------------------T---+---T-----------------T-+-T-+-T---------------------------------+------+----------+-------+-------------------------P---+-*-Q-----------------T-+-T-+-T------
4,5 2,8 0,4 2,0 4,5 8,10 12,6
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.