隣接要素の合計が元の配列と一致する別の順列を求めるC++プログラム
問題概要
n個の要素からなる配列Aがあるとします。関数F(p)は、配列pの隣接する要素同士の合計値を昇順にソートした配列として定義されます。すなわち、F(p) = sort([p1+p2, p2+p3, ..., pn-1+pn]) です。ここで、ある順列Aが与えられたとき、F(A)の結果が元の配列と完全に同じになる「別の」順列を見つけることが課題となります。
具体例
入力が A = [2, 1, 6, 5, 4, 3] の場合を考えてみましょう。このときの出力の一例は [1, 2, 5, 6, 3, 4] です。
まず元の配列について計算すると:
F(A) = sort([2+1, 1+6, 6+5, 5+4, 4+3]) = sort([3, 7, 11, 9, 7]) = [3, 7, 7, 9, 11]
一方、出力の候補 [1, 2, 5, 6, 3, 4] について計算すると:
sort([1+2, 2+5, 5+6, 6+3, 3+4]) = sort([3, 7, 11, 9, 7]) = [3, 7, 7, 9, 11]
両者の結果が一致していることが分かります。なお、条件を満たす答えは複数存在する可能性があります。
解法のアプローチ
この問題の鍵となるのは、配列を逆順にするという非常にシンプルな操作です。配列を反転させると、隣接する要素のペアは同じ組み合わせが逆向きに現れるだけなので、隣接要素の合計値の集合(マルチセット)は一切変わりません。その結果、ソート後のF(A)も必ず元の配列と同一になります。
アルゴリズムの手順
- 配列Aのサイズnを取得します。
- i を n-1 から 0 まで減らしながらループし、各要素 A[i] を出力します。
n := size of A
for initialize i := n - 1, when i >= 0, update (decrease i by 1), do:
print A[i]
C++での実装例
以下に実際のC++コードを示します。
#include <bits/stdc++.h>
using namespace std;
void solve(vector<int> A) {
int n = A.size();
for (int i = n - 1; i >= 0; i--)
cout << A[i] << ", ";
}
int main() {
vector<int> A = { 2, 1, 6, 5, 4, 3 };
solve(A);
}
入力
{ 2, 1, 6, 5, 4, 3 }
出力
3, 4, 5, 6, 1, 2,
まとめ
隣接要素の合計をソートした結果が等しくなる別の順列を求める問題では、元の配列を単純に逆順にすればよいことが分かりました。反転しても隣接ペアの合計の集合は不変であるため、時間計算量O(n)という非常に効率的な方法で解答を得ることができます。
-
C++で数の奇数の約数(奇因子)の合計を求めるプログラム
正の整数が与えられたとき、その数の奇数の約数(奇因子)をすべて求め、それらの合計を計算するのが本プログラムの目的です。 例 入力: number = 20 出力: 奇数の約数の合計は: 6 入力: number = 18 出力: 奇数の約数の合計は: 13 例えば number = 20 の場合、約数は 1, 2, 4, 5, 10, 20 ですが、このうち奇数は 1 と 5 のみです。したがって、結果 = 1 + 5 = 6 となります。 プログラムで使用するアプローチ 奇数の約数の合計を計算する対象の数を入力する 偶数の約数を除外するため、まず数を2で割り切れる限り2で割り続け、奇数の部
-
配列の全要素を乗算するC++プログラムの解説
整数型の要素を持つ配列が与えられたとき、配列内のすべての要素を掛け合わせ、その積を表示することを考えます。本記事では、この問題をC++(C言語スタイルのコード)で解く方法を、アプローチ、アルゴリズム、サンプルコード、実行結果まで順を追って解説します。 例 入力: arr[]={1,2,3,4,5,6,7} 出力: 1 x 2 x 3 x 4 x 5 x 6 x 7 = 5040 入力: arr[]={3, 4, 6, 2, 7, 8, 4} 出力: 3 x 4 x 6 x 2 x 7 x 8 x 4 = 32256 解き方のアプローチ この問題は、累積用の一時変数を用意し、配列の要素を先頭