Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonでn回の反転操作後のボールの位置を求めるプログラム

問題の概要

n個のボールがあり、初期状態では「1, 2, 3, ..., n」の順に並んでいるとします。まずボール全体を反転して「n, n-1, ..., 2, 1」の順序にします。続いて、開始位置を1つ右にずらしながら再度反転を行い、この操作を合計n回繰り返します。毎回、反転の開始位置は前回より1つ右へ移動していきます。

この一連の反転操作が完了した後、最初に「index」番目の位置にあったボールが最終的にどこへ移動するかを求めるのが、この記事で扱う問題です。

具体例

たとえば、balls = 5、index = 2 が入力された場合、出力は 4 になります。ボールの初期状態は次のとおりです。

1, 2, 3, 4, 5

各ステップでの反転結果は以下のように変化していきます。

5,4,3,2,1
5,1,2,3,4
5,1,4,3,2
5,1,4,2,3

この結果から、最初に2番目(0始まり)の位置にあったボールは、最終的に4番目の位置へ移動していることがわかります。

解法の考え方

この問題を実際に反転操作をシミュレーションしながら解くと、計算量はO(n²)になります。しかし、ボールの移動パターンを注意深く観察すると、定数時間O(1)で答えを導き出せることに気づきます。

手順は以下のとおりです。

  • index が balls // 2(balls を 2 で割った商の切り捨て値)より小さい場合:2 * index + 1 を返す
  • それ以外の場合:2 * (balls - index - 1) を返す

この式が成り立つ理由は、反転操作を繰り返すことで、前半に位置していたボールは奇数番号の位置へ、後半に位置していたボールは偶数番号の位置へ移動するという明確な規則性が生まれるためです。

実装例

理解を深めるために、Pythonでの実装例を見てみましょう。

def solve(balls, index):
if index < balls // 2:
return 2 * index + 1
else:
return 2 * (balls - index - 1)

print(solve(5, 2))

入力

5, 2

出力

4

まとめ

n個のボールに対して開始位置をずらしながらn回の反転を行う問題では、シミュレーションを実行しなくても、対象のボールが初期状態で前半に位置するか後半に位置するかを判定するだけで、O(1)で最終的な位置を計算できます。このように、規則性のある操作が繰り返される問題では、小さな入力でパターンを観察し数式化することが、効率的なアルゴリズムへの近道となります。

  1. Pythonでグラフがすべての人にとって移動可能かどうかを確認するプログラム

    n個の頂点(0からn-1までの番号が付けられたもの)から構成される無向グラフが与えられます。各辺には重みが設定されており、重みは「1」「2」「3」の3種類があります。このグラフを移動できるのはJackとCaseyの2人で、Jackは重み1の辺のみ、Caseyは重み2の辺のみを移動でき、重み3の辺は両方が移動できます。 ここで、JackとCaseyの両方がグラフ内のすべての頂点に到達できるようにするために、不要な辺を削除することを考えます。このとき削除が必要な辺の本数を求め、どのようにしても移動可能な状態にできない場合は-1を返します。 例えば、入力が次のような場合を考えてみましょう。 n =

  2. Pythonでグリッド内のボールの着地位置を求めるプログラム

    問題概要 m × n のグリッドボックスを考えます。各セルには、左上から右下、もしくは右上から左下へ向けて斜めの板が設置されています。グリッドの上端からボールを落とし、それぞれのボールが底まで到達できるか、そしてどの列に着地するのかを求めるのがこの問題です。 グリッドは行列として与えられ、各セルの値は板の向きを表します。 1: 左上から右下へ下る斜めの板 -1: 右上から左下へ下る斜めの板 n 個のボールを上端の各列から順に落としたとき、底に到達したボールの着地列を答えとして返します。途中で側面の壁に当たったり、V字型の溝にはまって動けなくなったボールについては -1 を出力します。 3