C++で対角線の合計と等しい行・列の個数を数える方法
本記事では、行と列から構成される2次元配列(行列)が与えられたとき、すべての行と列の合計を計算し、その値が主対角線または副対角線の合計と一致する個数を求める方法を解説します。
入力例1
int arr[row][col] = {
{ 4, 1, 7 },
{ 10, 3, 5 },
{ 2, 2, 11}
}
出力
対角線の合計と等しい行・列の個数:2
説明
主対角線の合計は 4 + 3 + 11 = 18、副対角線の合計は 7 + 3 + 2 = 12 です。まず各行の合計を確認しましょう。
- 1行目:4 + 1 + 7 = 12(一致)
- 2行目:10 + 3 + 5 = 18(一致)
- 3行目:2 + 2 + 11 = 15(不一致)
続いて各列の合計です。
- 1列目:4 + 10 + 2 = 16(不一致)
- 2列目:1 + 3 + 2 = 6(不一致)
- 3列目:7 + 5 + 11 = 23(不一致)
したがって、主対角線および副対角線の合計と一致する行・列の個数は 2 となります。
入力例2
int arr[row][col] = {
{ 1, 2, 3 },
{ 4, 5, 2 },
{ 7, 9, 10}
}
出力
対角線の合計と等しい行・列の個数:2
説明
主対角線の合計は 1 + 5 + 10 = 16、副対角線の合計は 7 + 3 + 5 = 15 です。各行の合計は以下のとおりです。
- 1行目:1 + 2 + 3 = 6(不一致)
- 2行目:4 + 5 + 2 = 11(不一致)
- 3行目:7 + 9 + 10 = 26(不一致)
各列の合計は以下のとおりです。
- 1列目:7 + 4 + 1 = 12(不一致)
- 2列目:9 + 5 + 2 = 16(一致)
- 3列目:3 + 2 + 10 = 15(一致)
この場合も、条件に一致する行・列の個数は 2 となります。
プログラムで使用するアプローチ
- 行サイズと列サイズをもつ2次元配列を作成し、行列を表現します。
- 主対角線と副対角線の合計を格納する変数、および結果を保存するカウント用変数を用意します。
- i を 0 から col 未満まで増加させ、同時に j を col - 1 から減少させるループを実行します。
- ループ内で principal に matrix[i][i] を加算し、secondary に matrix[i][j] を加算して、それぞれの対角線の合計を求めます。
- 次に i を 0 から col 未満まで回すループを開始します。
- ループ内で行の合計 r と列の合計 c を 0 に初期化し、さらに j を 0 から col 未満まで回す内部ループを設けます。
- 内部ループ内で r += matrix[i][j] として行の合計を計算します。
- 同様に c += matrix[j][i] として列の合計を計算します。
- (r == principal) || (r == secondary) が成立する場合は count を 1 増やします。
- (c == principal) || (c == secondary) が成立する場合も count を 1 増やします。
- 最後に count を返し、結果を出力します。
C++での実装例
#include <iostream>
#define row 3
#define col 3
using namespace std;
int diagonal_sum(int matrix[row][col]){
int principal = 0;
int secondary = 0;
int r = 0;
int c = 0;
int count = 0;
int i = 0, j = 0;
for (i = 0, j = col - 1; i < col; i++, j--){
principal += matrix[i][i];
secondary += matrix[i][j];
}
for (int i = 0; i < col; i++){
r = 0;
c = 0;
for (int j = 0; j < col; j++){
r += matrix[i][j];
}
for (int j = 0; j < col; j++){
c += matrix[j][i];
}
if ((r == principal) || (r == secondary)){
count++;
}
if ((c == principal) || (c == secondary)){
count++;
}
}
return count;
}
int main(){
int matrix[row][col] = {
{ 4, 1, 7 },
{ 10, 3, 5 },
{ 2, 2, 11}};
cout<<"Count of rows/columns with sum equals to diagonal sum are: "<<diagonal_sum(matrix);
return 0;
}
出力
上記のコードを実行すると、次の出力が得られます(「対角線の合計と等しい行・列の個数は 2」という意味です)。
Count of rows/columns with sum equals to diagonal sum are: 2
まとめ
このアルゴリズムでは、対角線の合計を1回のループで求めた後、各行・各列の合計を順番に計算して照合しています。全体の時間計算量は O(n²)、空間計算量は O(1) であり、追加のメモリを使わずに効率的に処理できる点が特徴です。
-
C++でXとの合計がフィボナッチ数になるノードを数える方法
各ノードに数値の重みが割り当てられた二分木が与えられます。この記事の目的は、「ノードの重み + X」の計算結果がフィボナッチ数となるノードの個数を求めることです。フィボナッチ数列とは、0, 1, 1, 2, 3, 5, 8, 13… のように続く数列で、n番目の数は(n−1)番目と(n−2)番目の数の和になります。たとえば重みが13であればフィボナッチ数に該当するため、そのノードはカウント対象となります。入力例1temp = 1 の場合。値を入力すると、以下のような木が構成されます。出力Count the nodes whose sum with X is a Fibonacci number
-
【C++】aの個数がbより多い部分文字列の総数を効率的に求める方法
この問題では、文字 a と b のみで構成された文字列 str と整数 N が与えられます。str を N 回繰り返して連結することで新しい文字列を作成し、その中に含まれる「a の出現回数が b より多い」部分文字列の総数を求めて出力するのが課題です。 問題の例 まず、具体的な例で問題を確認してみましょう。 入力: aab 2 出力: 9 説明: 作成された文字列は aabaab。 条件を満たす部分文字列: a, aa, aab, aaba, aabaa, aabaab, aba, baa, abaa 解法のアプローチ この問題を解くには、毎回完全な文字列を生成するのではなく、元の文字列 st