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

C++で配列内の合計が指定範囲[a, b]に収まるトリプレットの数を数える方法

問題の概要

整数型の配列 Arr[] と、範囲を定義する2つの変数 a・b が与えられます。この記事の目的は、3つの要素の合計が範囲 [a, b] の間に収まるトリプレット(3要素の組み合わせ)の個数を求めることです。

解法には3重の for ループを使用します。arr[i] + arr[j] + arr[k] が a 以上かつ b 以下を満たすたびにカウントを1増やします。添字の範囲は 0 <= i <= n-2、i < j < n-1、j < k < n です。ここで n は配列 Arr[] の要素数を表します。

具体例で確認してみましょう。

入力例1

入力 − arr[] = { 1, 2, 3, 4, 5 }, N = 5, L = 2, R = 8

出力 − トリプレットの数 − 4

説明

合計が2以上8以下のトリプレット
(1,2,3) → 6
(1,2,4) → 7
(1,2,5) → 8
(1,3,4) → 8
合計: 4個

入力例2

入力 − arr[] = { 2, 2, 2, 2, 2 }, N = 5, L = 2, R = 5

出力 − トリプレットの数 − 0

説明

すべてのトリプレットの合計は6となり、範囲 [2, 5] には含まれません。

合計: 0個

プログラムで使用するアプローチ

  • ランダムな数値で初期化した整数型配列 Arr[] を用意します。
  • 範囲 [L, R] を定義するための変数 L と R を用意し、N には配列 Arr[] の長さを格納します。
  • 関数 countTriplets(int arr[], int n, int a, int b) は、配列・その長さ・範囲の変数を引数として受け取り、合計が範囲内に収まるトリプレットの数を返します。
  • トリプレットの個数を数えるための変数 count を 0 で初期化します。
  • 各トリプレットの合計を格納する変数 sum を用意します。初期値は 0 です。
  • トリプレットの各要素に対応する3重の for ループで配列を走査します。
  • 最も外側のループは 0 <= i < n-2、内側のループは i < j < n-1、最も内側のループは j < k < n となります。
  • sum = arr[i] + arr[j] + arr[k] を計算し、a <= sum <= b であれば count をインクリメントします。
  • すべてのループが終わった時点で、count には条件を満たすトリプレットの総数が格納されています。
  • 最後に count を結果として返します。

なお、この手法は3重ループを使用するため計算量は O(n³) となります。小〜中規模の配列には十分実用的ですが、より大きな入力に対してはソートや二分探索を組み合わせた高速化も検討するとよいでしょう。

実装例

#include <bits/stdc++.h>
using namespace std;
int countTriplets(int arr[], int n, int a, int b){
    int count = 0;
    int sum = 0;
    for (int i = 0; i < n-2; i++){
        for (int j = i+1; j < n-1; j++){
            for (int k = j+1; k < n; k++){
                sum = arr[i] + arr[j] + arr[k];
                if (sum >= a && sum <= b){ // 範囲内かどうかを判定
                    count++;
                    // cout << endl << "a :" << arr[i] << " b :" << arr[j] << " c :" << arr[k]; // 表示用
                }
            }
        }
    }
    return count;
}
int main(){
    int Arr[] = { 5, 4, 3, 6, 8, 2 };
    int L = 9;
    int R = 15;
    int N = 6; // 配列の長さ
    cout << endl << "トリプレットの数 : " << countTriplets(Arr, N, L, R);
    return 0;
}

出力

上記のコードを実行すると、次の出力が得られます −

トリプレットの数 : 14
  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

  2. C++の配列パズル:減算演算子を使わずに「自分以外の要素の合計」を求める方法

    今回は、配列に関する興味深い問題を紹介します。n個の要素を持つ配列が与えられ、それをもとに同じくn個の要素を持つ別の配列を作成します。ただし、新しい配列のi番目には、元の配列のi番目の要素を除いたすべての要素の合計を格納します。さらに重要な制約として、減算演算子(-)を使用してはいけないという条件が課されています。 問題のポイント もし減算が使えるのであれば、話は簡単です。まず全要素の合計を求めておき、そこからi番目の要素を引いた値を新しい配列のi番目に格納すればよいだけです。しかし、この問題では減算が禁止されているため、別のアプローチが必要になります。 そこで、各位置i(0〜n-1)について