C++で解くバイナリマトリックスの最大10進値パス問題
問題概要
与えられた正方バイナリ配列(2次元配列)において、左上の要素であるインデックス [0][0] から右下の要素であるインデックス [n−1][n−1] まで移動する経路の中で、得られる最大の整数値を求めるのが課題です。
経路の移動中に進むことができるのは、右方向([i][j+1])または下方向([i+1][j])のみです。
そして整数値は、通過した経路上のビットを用いて計算されます。
それでは、具体例を使って何をすべきか確認していきましょう。
入力
m = {
{1, 1, 1, 1},
{0, 0, 1, 0},
{1, 0, 1, 1},
{0, 1, 1, 1}
}
出力
127
説明
今回選んだ経路は次のとおりです。[0, 0] → [0, 1] → [0, 2] → [1, 2] → [2, 2] → [3, 2] → [3, 3]
したがって、10進値は以下のように計算されます。
1×(20) + 1×(21) + 1×(22) + 1×(23) + 1×(24) + 1×(25) + 1×(26)
= 1 + 2 + 4 + 8 + 16 + 32 + 64
= 127
入力
m = {
{1, 0, 1, 1},
{0, 0, 1, 0},
{1, 0, 0, 1},
{0, 1, 1, 1}
}
出力
109
プログラムで使用しているアプローチ
まず #define を使って、正方行列の一辺のサイズを冒頭で定義します。
main() 関数内で、行列を格納するための2次元配列 int m[][4] を作成し、Max(m, 0, 0, 0) を呼び出します。
Max() 関数では、まず (i >= side || j >= side) であるかどうかを判定します。該当する場合は行列の境界外にいることを意味するため、0 を返します。
新しい変数 int ans を作成し、ans = max(Max(m, i, j+1, pw+1), Max(m, i+1, j, pw+1)) を代入します。
続いて (m[i][j] == 1) であるかどうかを判定し、該当する場合は pow(2, pw) + ans を返します。
そうでない場合は、単純に ans を返します。
コード例
#include<bits/stdc++.h>
using namespace std;
#define side 4
// pw は 2 のべき乗を表す
int Max(int m[][side], int i, int j, int pw){
// 行列の境界外の場合
if (i >= side || j >= side)
return 0;
int ans = max(Max(m, i, j+1, pw+1), Max(m, i+1, j, pw+1));
if (m[i][j] == 1)
return pow(2, pw) + ans;
else
return ans;
}
// main関数
int main(){
int m[][4] = {{1, 1, 1, 1},{0, 0, 1, 0},{1, 0, 1, 1},{0, 1, 1, 1}};
cout << Max(m, 0, 0, 0);
return 0;
}
出力
127
-
C++で最大二分木を構築する方法:再帰アルゴリズムと実装例を解説
最大二分木(Maximum Binary Tree)とは? ここでは、すべての要素が一意(重複なし)である整数配列が与えられたとします。この配列から構築される「最大二分木」は、以下のように定義されます。 根(ルート)には、配列内の最大値が格納されます。 左部分木は、最大値を基準に分割された左側の部分配列から構築された最大二分木です。 右部分木は、最大値を基準に分割された右側の部分配列から構築された最大二分木です。 この定義に従って最大二分木を構築します。たとえば、入力が [3,2,1,6,0,5] の場合、構築される木は次の図のようになります。 解き方のアプローチ この問題は、再帰的な
-
C++で二分木における2つの葉ノード間の最大パス合計を求める方法
問題の概要 この問題では、各ノードが値を持つ二分木が与えられます。私たちのタスクは、二分木における2つの葉ノード(リーフノード)間の最大パス合計を求めるプログラムを作成することです。 ここで求めるのは、値の合計が最大になるような、ある葉ノードから別の葉ノードへのパスです。この最大合計パスには、ルートノードが含まれる場合もあれば、含まれない場合もあります。 二分木(Binary Tree)とは、各ノードが最大2つの子ノードを持つことができる木構造のデータ構造です。それぞれの子ノードは「左の子(left child)」と「右の子(right child)」と呼ばれます。 具体例 以下のような二分木