C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++で積と和の差が指定値DとなるN個の整数を見つける方法

問題の概要

2つの整数NとDが与えられたとき、それらの合計の差がちょうどDと等しくなるような、N個の整数の集合を見つける必要があります。

例えば、N=3、D=5の場合、答えは「1, 2, 8」です。このとき合計は 1 + 2 + 8 = 11、積は 1 × 2 × 8 = 16 となり、16と11の差はちょうど5(= D)になります。

解法のアプローチ:巧妙な構成テクニック

この問題を効率的に解くには、次のような構成を利用します。

  • N−2個の「1」
  • 1つの「2」
  • 残りの1つとして「N + D」

この構成を採用すると、合計・積・差はそれぞれ以下のように計算できます。

  • 合計 = (N − 2) × 1 + 2 + (N + D) = 2N + D
  • 積 = (N − 2) × 1 × 2 × (N + D) = 2N + 2D
  • 差 = (2N + 2D) − (2N + D) = D

このように、与えられるNとDの値が何であっても、この構成方法を使えば必ず条件を満たす整数の集合を得られることが数学的に保証されます。探索を行う必要がないため、計算量はO(N)と非常に効率的です。

C++での実装例

#include<iostream>
using namespace std;

void getNNumbers(int n, int d) {
    // N-2個の1を出力
    for (int i = 0; i < n - 2; i++)
        cout << 1 << " ";
    // 2を出力
    cout << 2 << " ";
    // N + D を出力
    cout << n + d << endl;
}

int main() {
    int N = 5, D = 8;
    getNNumbers(N, D);
}

出力結果

1 1 1 2 13

N=5、D=8の場合の出力は「1 1 1 2 13」です。検証してみると、合計は 1 + 1 + 1 + 2 + 13 = 18、積は 1 × 1 × 1 × 2 × 13 = 26 となり、その差は 26 − 18 = 8 で、確かにDと一致しています。

まとめ

本問題は、一見すると複雑な組み合わせ探索が必要に思えますが、「1を複数個使うと積に影響しない」という性質を利用することで、シンプルな公式ベースの解法に帰着できます。競技プログラミングなどで役立つ定番テクニックの一つなので、ぜひ覚えておきましょう。

  1. C++で平衡二分探索木から目標合計となるペアを見つける方法

    平衡二分探索木(Balanced BST)と目標値(target sum)が与えられたとき、合計が目標値と等しくなるペアが木の中に存在するかどうかを判定するメソッドを実装することを考えます。この際、二分探索木は不変(immutable)である、つまり木の構造を変更してはいけないという制約があることに注意が必要です。例えば、入力が以下のような木だったとします。この場合、出力は (9 + 26 = 35) となります。解決アプローチこの問題は、ソート済み配列でよく使われる「二ポインタ(Two Pointers)」手法を、二分探索木に応用することで解けます。具体的には、以下の2つの走査を同時に進めて

  2. C言語とC++の構造体の違いを徹底解説

    本記事では、C言語の構造体とC++の構造体の違いについて詳しく解説します。C++の構造体は、C++のクラスとほぼ同じ性質を持っています。大きな違いのひとつとして、C言語の構造体ではすべてのメンバーがpublic(公開)であるのに対し、C++の構造体ではデフォルトでprivate(非公開)になる点が挙げられます。その他の違いについても、以下の表にまとめてご紹介します。C構造体とC++構造体の比較表C言語の構造体C++の構造体構造体内にメンバー関数を定義することはできません。メンバー変数に加えて、メンバー関数も定義できます。構造体のデータメンバーを宣言時に直接初期化することはできません。構造体のデ