C++でマトリックス上の2点間の単一移動方向を判定する方法
問題概要
この問題では、2つの点 (x1, y1) と (x2, y2) を表す4つの整数値 x1、y1、x2、y2 が与えられます。求めるのは、始点 (x1, y1) から終点 (x2, y2) へたった1回の移動で到達するための方向です。マトリックス上での移動に使える方向は1つだけで、答えは「Left(左)」「Right(右)」「Up(上)」「Down(下)」のいずれかの形式で返します。どの一方向でも到達できない場合は -1 を返し、「不可能」であることを示します。
入力例
x1 = 2, y1 = 1, x2 = 5, y2 = 1
出力例
Down
解き方のアプローチ
この問題のポイントは、「始点から終点へ1回の直線移動で到達するには、x座標(x1とx2)またはy座標(y1とy2)のどちらか一方が必ず等しくなる」という性質を利用することです。片方の座標だけが変化する場合、その変化の向きから移動方向を一意に決定できます。
条件を整理すると、以下の4つのケースに分類されます。
ケース1: x1 == x2 かつ y1 > y2 の場合 → 方向 : Left(左) ケース2: x1 == x2 かつ y2 > y1 の場合 → 方向 : Right(右) ケース3: y1 == y2 かつ x1 > x2 の場合 → 方向 : Up(上) ケース4: y1 == y2 かつ x2 > x1 の場合 → 方向 : Down(下)
反対に、x座標とy座標の両方が異なる場合は斜め移動が必要になるため、1回の移動では到達できず「Not Possible(不可能)」と判定されます。
C++による実装例
以下は、このソリューションの動作を示すC++プログラムです。
#include <iostream>
using namespace std;
void findSingleMovement(int x1, int y1, int x2, int y2) {
if (x1 == x2 && y1 < y2)
cout<<"Right";
else if (x1 == x2 && y1 > y2)
cout<<"Left";
else if (y1 == y2 && x1 < x2)
cout<<"Down";
else if (y1 == y2 && x1 > x2)
cout<<"Up";
else
cout<<"Not Possible";
}
int main() {
int x1, x2, y1, y2;
x1 = 2; y1 = 1;
x2 = 5; y2 = 1;
cout<<"The direction of movement is ";
findSingleMovement(x1, y1, x2, y2);
return 0;
}
実行結果
The direction of movement is Down
まとめ
本アルゴリズムは座標の比較だけで方向を判定できるため、時間計算量・空間計算量はともに O(1) と非常に効率的です。2点が同じ行または同じ列上にあるかを確認するだけでよいので、実装もシンプルで実用的です。
-
C++で二分木における単一値の部分木を数える方法
二分木が与えられたとき、その木に含まれる「単一値の部分木(Single Valued Subtree)」の個数を求めるのが本記事の目的です。単一値の部分木とは、その部分木を構成するすべてのノードが同じ値を持つような部分木のことを指します。問題の例例として、次のような二分木を考えてみましょう。この木には、以下に示す4つの単一値の部分木が存在します。解法のアプローチ:ボトムアップ方式この問題は、ボトムアップ(下から上へ)の再帰的なアプローチで効率的に解くことができます。基本的な考え方は次のとおりです。各ノードを訪問する際、そのノードを根とする部分木が単一値であるかどうかを判定し、単一値であればカウ
-
C++で行列の転置を求めるプログラムの書き方【サンプルコード付き解説】
行列とは、数値を行と列の形式に整理して並べた長方形の配列のことです。そして「転置行列」とは、元の行列の行を列に、列を行に入れ替えて作られる新しい行列を指します。転置行列のイメージ例として、次のような3×3の行列を見てみましょう。1 2 3 4 5 6 7 8 9この行列を転置すると、次のようになります。1 4 7 2 5 8 3 6 9元の行列の1行目(1, 2, 3)が、転置後には1列目になっていることが分かります。このように、元の行列の要素 a[i][j] は、転置後には a[j][i] の位置へ移動します。C++による転置行列を求めるプログラム以下が、C++で行列の転置を求めるプログラム