C++で要素を1つ追加して配列を等差数列に変換する方法
このチュートリアルでは、要素を1つ追加することで、与えられた配列を等差数列(算術数列)に変換するプログラムについて解説します。
ここでは、整数の配列が与えられます。私たちのタスクは、その配列に要素を1つだけ追加して等差数列へと変換し、追加した要素の値を返すことです。もし等差数列への変換が不可能な場合は、-1 を返します。
アルゴリズムの考え方
まず配列を昇順にソートし、最初の2つの要素の差を公差 d とします。その後、3番目以降の要素について、隣接する要素間の差を順番に確認していきます。
- すべての差が
dと一致すれば、配列はすでに等差数列になっているため、末尾の要素にdを加えた値を返します。 - 差が
2dとなっている箇所が1箇所だけあれば、そこにarr[i] - dの値を挿入することで等差数列にできます。 - 不整合が2箇所以上ある場合や、差が
dでも2dでもない場合は、変換は不可能なので-1を返します。
サンプルコード
#include<bits/stdc++.h>
using namespace std;
// 追加すべき数値を返す関数
int print_number(int arr[], int n){
sort(arr,arr+n);
int d = arr[1] - arr[0];
int numToAdd = -1;
bool numAdded = false;
for (int i = 2; i < n; i++) {
int diff = arr[i] - arr[i - 1];
if (diff != d) {
if (numAdded)
return -1;
if (diff == 2 * d) {
numToAdd = arr[i] - d;
// 数値を追加済みの場合
numAdded = true;
}
// 変換が不可能な場合
else
return -1;
}
}
// 末尾の要素 + 公差を返す
if (numToAdd == -1)
return (arr[n - 1] + d);
// 選択した数値を返す
return numToAdd;
}
int main() {
int arr[] = { 1, 3, 5, 7, 11, 13, 15 };
int n = sizeof(arr)/sizeof(arr[0]);
cout << print_number(arr, n);
}
出力
9
コードの解説
上記の例では、配列 {1, 3, 5, 7, 11, 13, 15} が与えられています。ソート後の公差は d = 2 ですが、7 と 11 の間の差だけが 4(= 2d)となっています。そこで 9 を挿入すれば、{1, 3, 5, 7, 9, 11, 13, 15} という完全な等差数列になります。そのため、プログラムは追加すべき値として 9 を出力します。
このアルゴリズムの計算量は、ソートに O(n log n)、走査に O(n) となるため、全体の時間計算量は O(n log n) です。空間計算量は O(1) で、非常に効率的なアプローチと言えます。
-
C++で配列要素の階乗の最大公約数(GCD)を求める方法
N個の要素を持つ配列Aが与えられたとき、配列内のすべての要素の階乗の最大公約数(GCD)を求めることを考えます。例えば、配列の要素が {3, 4, 8, 6} の場合、各要素の階乗は 3! = 6、4! = 24、8! = 40320、6! = 720 となり、これらのGCDは 6 になります。解法のポイントここで重要な数学的な性質があります。2つの数のGCDとは、両方の数を割り切る最大の数のことです。階乗の場合、小さい数の階乗は必ず大きい数の階乗を割り切ることができます。つまり、2つの階乗のGCDは、小さい方の数の階乗そのものになります。例えば、3! と 5! のGCDを考えると、3! =
-
C++で配列の全要素がK以上になるまで最小要素を加算する方法
配列(Array)とは、同じデータ型の要素を格納するコンテナであり、各要素は0から始まるインデックスで管理されます。この記事では、整数型の配列を扱い、配列内のすべての要素が指定された数値以上であるかどうかを確認します。具体的には、配列のすべての要素が与えられた数値 K 以上になっているかを判定し、条件を満たしていない場合は、配列内で最も小さい2つの要素を取り出して合計し、その合計値を1つの新しい要素として扱います。その後、再び同じ条件で新しい配列をチェックします。条件が満たされれば、加算を実行した回数を結果として返します。問題例Array = { 2, 6, 3, 12, 7 } K = 5