Pythonで行列上の爆弾ですべての敵を倒せるかどうかを判定する方法
ここでは、行列 mat が与えられたとき、そのセルには次の3種類の値が格納されているものとします。
- 0: 空きエリア
- 1: 爆弾
- 2: 敵
爆弾は、上下左右(水平・垂直方向)の一端からもう一端まで爆発して範囲内を破壊します。このとき、すべての敵が爆発によって倒されるかどうかを判定するのが本記事の目的です。
問題の例
たとえば、次のような入力が与えられたとします。
| 0 | 0 | 2 | 0 |
| 0 | 1 | 0 | 0 |
| 0 | 2 | 0 | 0 |
| 0 | 0 | 1 | 0 |
この場合の出力は True になります。その理由は以下の通りです。
- 位置 [1, 1] の爆弾が縦方向に爆発し、位置 [2, 1] の敵を倒します。
- 位置 [3, 2] の爆弾が縦方向に爆発し、位置 [0, 2] の敵を倒します。
結果として、すべての敵が爆発の範囲内に含まれるため、答えは True となります。
解決のためのアルゴリズム
この問題は、次の手順で解くことができます。
- r := 行列 mat の行数、c := 列数 を取得します。
- すべてのセルを走査し、値が 1(爆弾)であるセルを見つけます。
- 爆弾が見つかったら、その列全体と行全体に対して、爆弾以外のセル(敵や空きエリア)をすべて 0 に書き換えます。これにより爆発の影響範囲を表現できます。
- すべての爆弾について処理が完了したら、再度行列を走査します。
- まだ値が 2(敵)として残っているセルが存在すれば
Falseを返します。 - 敵がひとつも残っていなければ
Trueを返します。
Pythonでの実装例
それでは、実際のコードを見てみましょう。
def solve(mat):
r = len(mat)
c = len(mat[0])
i, j, x, y = 0, 0, 0, 0
for i in range(r):
for j in range(c):
if mat[i][j] == 1:
for x in range(r):
if mat[x][j] != 1:
mat[x][j] = 0
for y in range(c):
if mat[i][y] != 1:
mat[i][y] = 0
for i in range(r):
for j in range(c):
if mat[i][j] == 2:
return False
return True
matrix = [ [0,0,2,0], [0,1,0,0], [0,2,0,0], [0,0,1,0] ]
print(solve(matrix))入力
[ [0,0,2,0], [0,1,0,0], [0,2,0,0], [0,0,1,0] ]
出力
True
コードのポイント
- 最初の二重ループで爆弾(1)の位置を検出し、その行・列を順に 0 で埋めていくことで「爆発済み」の状態を再現しています。
- 爆弾自体(値が 1 のセル)は上書きしないため、複数の爆弾が同じ行・列にある場合でも正しく処理されます。
- 最後にもう一度行列を走査し、敵(2)が残っていないかを確認することで判定を行います。
このように、爆発の影響範囲をシミュレートしてから残存する敵の有無を確認するというシンプルなアプローチで、問題を効率的に解くことができます。
-
Pythonで2つの二分木の全レベルがアナグラムかどうかを判定する方法
問題概要 2つの二分木が与えられたとき、片方の木の各レベルに含まれる値の集合が、もう片方の木の同じレベルの値のアナグラム(並べ替え)になっているかどうかを判定します。すべてのレベルがアナグラムであれば True を、そうでなければ False を返します。 例えば、次のような入力が与えられた場合を考えてみましょう。 この場合、出力は True になります。 解法のアプローチ この問題は、幅優先探索(BFS)を応用して解くことができます。各レベルごとにノードの値を収集し、ソートした上で比較するのがポイントです。手順は以下の通りです。 tree_1 を1つ目の木のルートノード、tree_2 を
-
【Python入門】2つの行列が同一かどうかを判定するプログラムの書き方
この記事では、与えられた2つの行列(マトリックス)が同一であるかどうかを判定するPythonプログラムを紹介します。2つの行列が同一であるためには、次の条件を満たす必要があります。 両行列の行数・列数(次数)が一致していること 対応するすべての要素が等しいこと これらの条件を1つでも満たさない場合、2つの行列は同一とはみなされません。 アルゴリズム 判定の手順は以下の通りです。計算量は O(n²)(n×n行列の場合)となります。 ステップ1: 2つの行列を作成する。 ステップ2: 1つ目の行列と2つ目の行列のすべての要素を走査し、 対応する要素同士を順番に比較する