C++で最大の正方形を見つける方法|動的計画法による解説
問題概要
0 と 1 のみで構成された 2 次元バイナリ行列が与えられます。この中から「1」だけで構成される最大の正方形を見つけ、その面積を返してください。
たとえば、次のような行列が与えられたとしましょう。
| 1 | 0 | 1 | 0 | 0 |
| 1 | 0 | 1 | 1 | 1 |
| 1 | 1 | 1 | 1 | 1 |
| 1 | 0 | 0 | 1 | 0 |
この場合、2行目と3行目にまたがる 2×2 の正方形が存在するため、出力は 4 となります。
アルゴリズム:動的計画法
この問題は動的計画法(DP)を使うことで効率的に解けます。元の行列と同じサイズの補助行列 m を用意し、各セル m[i][j] には「位置 (i, j) を右下の角とする最大の正方形の一辺の長さ」を記録していきます。
具体的な手順は以下の通りです。
- ans := 0、n := 行数、c := 列数 とする
- n が 0 の場合は 0 を返す
- n × c のサイズの補助行列 m を作成する
- i を 0 から n−1 まで、j を 0 から c−1 まで繰り返す
- m[i][j] := matrix[i][j](文字 '1' / '0' を整数に変換して代入)
- ans := max(m[i][j], ans)
- i を n−2 から 0 まで逆順に、j を 1 から c−1 まで繰り返す
- m[i][j] が 0 でない場合、m[i][j] := 1 + min(m[i+1][j], m[i][j−1], m[i+1][j−1])
- ans := max(ans, m[i][j])
- 最後に ans × ans を返す
なぜこの漸化式が成立するのか
あるセルが「1」のとき、そのセルを右下とする正方形の一辺の長さは、真下・左・左下の 3 つのセルの値の最小値に 1 を加えたものになります。これは、3 方向すべてが十分な長さの正方形を持っていなければ、それより大きい正方形は作れないためです。最も大きい一辺の長さを ans として追跡し、最後に 2 乗することで面積が求まります。
C++ 実装例
それでは、実際の C++ コードで確認してみましょう。
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
int maximalSquare(vector<vector<char>>& matrix) {
int ans = 0;
int n = matrix.size();
if(!n) return 0;
int c = matrix[0].size();
vector<vector<int>> m(n, vector<int>(c));
for(int i = 0; i < n; i++){
for(int j = 0; j < c; j++){
m[i][j] = matrix[i][j] - '0';
ans = max(m[i][j], ans);
}
}
for(int i = n - 2; i >= 0; i--){
for(int j = 1; j < c; j++){
if(m[i][j]){
m[i][j] = 1 + min({m[i+1][j], m[i][j-1], m[i+1][j-1]});
}
ans = max(ans, m[i][j]);
}
}
return ans * ans;
}
};
main(){
vector<vector<char>> v = {{'1','0','1','0','0'},{'1','0','1','1','1'},{'1','1','1','1','1'},{'1','0','0','1','0'}};
Solution ob;
cout << ob.maximalSquare(v);
}
入力
[["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
出力
4
計算量
- 時間計算量:O(n × c) — 行列の全セルをそれぞれ一度ずつ処理するだけです。
- 空間計算量:O(n × c) — 元の行列と同じサイズの補助行列 m が必要です。
-
C++で正方形の外接円の面積を求める方法
本記事では、正方形の一辺の長さが与えられたときに、その正方形の外接円の面積を求める方法について解説します。まず、理解を深めるために基本的な定義をおさらいしましょう。 基本用語の定義 正方形:すべての辺の長さが等しい四角形のことです。 外接円:多角形のすべての頂点に接する円のことです。 面積:二次元図形の広がりの大きさを数量的に表したものです。 外接円の面積の求め方 正方形の外接円の面積を計算するには、円と正方形それぞれのパラメータの間にある関係を見つける必要があります。 下の図のように、正方形のすべての頂点が円に接しています。この図から読み取れる重要な性質は、正方形の対角線の長さが円の直径
-
C++で正方形の面積を求めるプログラムの書き方
本記事では、正方形の一辺が与えられたときに、その一辺をもとに正方形の面積を計算して出力するC++プログラムを紹介します。 正方形とは 正方形とは、4つの辺と4つの角(すべて90度)を持つ2次元の平面図形であり、すべての辺の長さが等しいという特徴があります。言い換えれば、正方形とは「すべての辺の長さが等しい長方形」の一種であるとも言えます。 正方形のイメージは以下の通りです。 正方形の面積 = 一辺 × 一辺 入力例と出力例 入力:6 出力:36 一辺が6なので、出力は 6×6=36 となります。 入力:12 出力:144 アルゴリズム 処理の流れは以下のようになります。 関数 int m