C++で行列内の正方形の最大辺の長さを求めるアルゴリズム
この問題では、サイズ n × n の2次元行列 mat[][] が与えられます(n は奇数)。求めるのは、行列と同じ中心を持ち、外周の値がすべて等しい正方形の最大の辺の長さです。
問題の概要
与えられた行列の中から、行列の中心を共有する正方形の部分行列を探し、その外周(周囲)を構成する要素がすべて同じ値である場合に、その正方形の辺の長さを返します。条件を満たす複数の正方形がある場合は、最も大きいものを選びます。
入力例
mat[][] = {
{2, 4, 6, 6, 5},
{1, 7, 7, 7, 3},
{5, 7, 0, 7, 1},
{3, 7, 7, 7, 1},
{2, 0, 1, 3, 2}
}出力例
3
この例では、中心 (2, 2) を共有するサイズ 3×3 の部分行列があり、その外周はすべて「7」で構成されているため、答えは 3 となります。
解法のアプローチ
シンプルな解き方は次の通りです。まず、行列のサイズが奇数であるため、中心要素は必ずインデックス (n/2, n/2) の位置に存在します。中心を見つけたら、その周囲にある各サイズの部分行列(同心正方形)を順に調べ、外周の要素がすべて同じ値かどうかを確認します。
具体的には、中心から距離 i だけ離れた部分行列について、行 (n/2 - i) と (n/2 + i)、および列 (n/2 - i) と (n/2 + i) に含まれる要素が外周を形成します。i を 0 から n/2 まで変化させながら、外周の全要素が同一の値を持つかどうかをチェックしていきます。
アルゴリズムの手順
- 初期値として最大辺の長さを 1 に設定します(中心要素のみの正方形)。
- i を 0 から n/2 - 1 までループします。
- 各 i に対して、対応する同心正方形の外周4辺(上・下・左・右)の要素を走査します。
- 外周のすべての要素が同じ値であれば、その正方形の辺の長さ
n - 2 * iを候補として記録します。 - ループ終了後、記録された最大の辺の長さを返します。
C++による実装例
#include <iostream>
#define n 5
using namespace std;
int findMaxSideSquare(int matrix[][n]) {
int squareLen = 1;
for (int i = 0; i < n / 2; i++) {
int sideVal = matrix[i][i];
bool isSquare = true;
for (int j = i; j < n - i; j++) {
if (matrix[i][j] != sideVal)
isSquare = false;
if (matrix[n - i - 1][j] != sideVal)
isSquare = false;
if (matrix[j][i] != sideVal)
isSquare = false;
if (matrix[j][n - i - 1] != sideVal)
isSquare = false;
}
if (isSquare)
squareLen = n - 2 * i;
}
return squareLen;
}
int main() {
int mat[n][n] = {
{2, 4, 6, 6, 5},
{1, 7, 7, 7, 3},
{5, 7, 0, 7, 1},
{3, 7, 7, 7, 1},
{2, 0, 1, 3, 2}
};
cout<<"The maximum side length of square in a Matrix is "<<findMaxSideSquare(mat);
return 0;
}実行結果
The maximum side length of square in a Matrix is 3
計算量について
このアルゴリズムの時間計算量は O(n²) です。外側のループが n/2 回実行され、各反復で外周の走査に O(n) かかるためです。空間計算量は追加のデータ構造を使用しないため O(1) となり、非常に効率的な実装と言えます。
-
C++を使って行列内で合計が最大の列を見つける方法
ここでは、サイズ M × N の行列が与えられたときに、要素の合計が最大となる列を見つける方法を解説します。この問題では、難しいアルゴリズムを用いる必要はありません。行列を列方向に走査して各列の合計値を計算し、その合計が最大であれば、合計値と該当する列のインデックスを出力するというシンプルなアプローチで十分です。アルゴリズムの手順処理の流れは以下の通りです。1. 最大合計値を格納する変数 maxSum を INT_MIN で初期化し、列のインデックスを格納する index を -1 に設定します。2. 各列(0 ~ N-1)について、colSum 関数を使ってその列の要素の合計を計算します。3
-
Pythonで2値行列の最大パス長を求めるアルゴリズムを解説
この問題では、各要素が0または1であるm×nの正方行列mat[][]が与えられます。要素が1の場合は「接続されている」ことを、0の場合は「接続されていない」ことを意味します。私たちのタスクは、この2値行列における最大パス長を見つけることです。問題の説明この問題を解くには、行列上の最も長いパス、つまり行列内のすべての1の要素をつなぐ経路の最大長を求める必要があります。ただし、パスを求める前に、最大で1つの0を1に変換することが許されています。この変換をうまく行うことで、パス長を最大化できるのがポイントです。具体例で問題を確認してみましょう。入力例mat[][] = {{1, 0}, {0, 1}