Pythonで各建物の高さをスカイラインを維持したまま最大まで増加させる行列を求めるプログラム
問題の概要
2次元の行列を考えてみましょう。ここで matrix[r][c] は、都市にあるマンション(建物)の高さを表します。東西方向のスカイラインは行列の各行の最大値を取ることで得られ、南北方向のスカイラインは各列の最大値を取ることで得られます。
この記事のゴールは、東西・南北どちらのスカイラインも一切変えずに、各建物の高さを可能な限り最大まで引き上げた新しい行列を作ることです。
入力例
| 2 | 3 | 4 |
| 5 | 6 | 7 |
| 8 | 9 | 10 |
出力例
| 4 | 4 | 4 |
| 7 | 7 | 7 |
| 8 | 9 | 10 |
この場合、東西方向のスカイラインは [4, 7, 10]、南北方向のスカイラインは [8, 9, 10] です。1行目のすべての値を4に、2行目のすべての値を7に引き上げても、スカイラインは変化しません。これが「可能な限り高さを増やす」という意味です。
解法のアプローチ
この問題は、以下の手順で解くことができます。
r:= 行列の各行の最大値からなるリストc:= 行列の各列の最大値からなるリストi を 0 から行数まで繰り返す
j を 0 から列数まで繰り返す
r[i] < c[j]の場合:matrix[i][j] := r[i]それ以外の場合:
matrix[i][j] := c[j]
matrix を返す
ポイントは、各セルに対して「その行の最大値」と「その列の最大値」のうち小さい方を設定することです。そうすることで、各行・各列の最大値(つまりスカイライン)が変わらない範囲で、各セルを理論上の上限まで高くできます。
Pythonでの実装例
それでは、実際のコードを見てみましょう。
class Solution: def solve(self, matrix): r = [max(i) for i in matrix] c = [max(i) for i in zip(*matrix)] for i in range(len(matrix)): for j in range(len(matrix[i])): if r[i] < c[j]: matrix[i][j] = r[i] else: matrix[i][j] = c[j] return matrix ob = Solution() matrix = [ [2, 3, 4], [5, 6, 7], [8, 9, 10] ] print(ob.solve(matrix))
入力
[[2, 3, 4], [5, 6, 7], [8, 9, 10]]
出力
[[4, 4, 4], [7, 7, 7], [8, 9, 10]]
この実装では、zip(*matrix) を使うことで行列を転置し、各列の最大値を簡単に取得しています。計算量は O(R×C)(Rは行数、Cは列数)となり、非常に効率的です。
-
Pythonで行列の転置を求めるプログラム
この記事では、与えられた問題に対する解法とアプローチについて詳しく解説します。 問題文 ある行列が与えられたとき、その転置を同じ行列に格納し、結果を表示する必要があります。 行列の転置とは、行を列に、列を行に入れ替えたものです。言い換えれば、行列Aの転置は、要素A[i][j]をA[j][i]と入れ替えることで得られます。 実装例 N = 4 def transpose(A): for i in range(N): for j in range(i+1, N): A[i][j], A[j][i] = A[j][i], A[i][j] # ドライ
-
Pythonで円柱の周囲長を求めるプログラムの書き方
この記事では、以下の問題をPythonを使って解く方法を解説します。 問題の定義 問題: 直径と高さを入力として受け取り、円柱の周囲長を求める。 ここでいう「周囲長」とは、円柱を横から見たときに現れる長方形の外周のことです。つまり、円柱の側面を展開すると長方形になり、その縦が円柱の高さ、横が円の直径(円周ではありません)に相当します。 したがって、周囲長は次の式で表せます。 周囲長 = 2 × ( 高さ h + 直径 d ) d:円柱の直径 h:円柱の高さ 実装例 それでは、実際のコードを見てみましょう。 # 円柱の周囲長を計算する関数 def perimeter(diameter, he