C++の3つの配列からの要素を持つ特別なトリプレットの合計
この問題では、3つの配列X、Y、Zが与えられます。私たちのタスクは、3つの配列からの要素を持つ特別なトリプレットの合計を見つけるプログラムを作成することです。
特別なトリプレット 次のプロパティを保持する特殊なタイプのトリプレットです-
(a、b、c)の場合:a≤bおよびb≥c、 つまり、トリプレットの中央の要素は、他の2つの要素よりもグリーターである必要があります。
そして、トリプレットの値は次の式で与えられます-
f(a, b, c) = (a+b) * (b+c)
このトリプレットを作成するには、指定された3つの配列から互いに1つの要素を使用する必要があります。
問題を理解するために例を見てみましょう
入力 −
X[] = {5, 9, 4} ; Y[] = {8, 6} ; Z[] = {7, 1} 出力
説明 −すべての特別なトリプレットの値を見つけましょう。
(5, 8, 7) : value = (5+8) * (8+7) = 195 (5, 8, 1) : value = (5+8) * (8+1) = 117 (4, 8, 7) : value = (4+8) * (8+7) = 180 (4, 8, 1) : value = (4+8) * (8+1) = 108 (5, 6, 1) : value = (5+6) * (6+1) = 77 (4, 6, 1) : value = (4+6) * (6+1) = 70 Sum of special triplets = 747
この問題の簡単な解決策は、アレイからすべてのトリプレットを生成することです。すべての特殊なトリプレットについて、上記の式を使用してその値を計算します。そして、それらを合計変数に追加して、最終的な合計を返します。
例
ソリューションを説明するプログラム
#include <iostream>
using namespace std;
int findSpecialTripletSum(int X[], int Y[], int Z[], int sizeX, int sizeY, int sizeZ) {
int sum = 0;
for (int i = 0; i < sizeX; i++) {
for (int j = 0; j < sizeY; j++) {
for (int k = 0; k < sizeZ; k++) {
if (X[i] <= Y[j] && Z[k] <= Y[j])
sum = sum + (X[i] + Y[j]) * (Y[j] + Z[k]);
}
}
}
return sum;
}
int main() {
int X[] = {5, 9, 4};
int Y[] = {8, 6};
int Z[] = {7, 1};
int sizeX = sizeof(X) / sizeof(X[0]);
int sizeY = sizeof(Y) / sizeof(Y[0]);
int sizeZ = sizeof(Z) / sizeof(Z[0]);
cout<<"Sum of special triplets = "<<findSpecialTripletSum(X, Y, Z,
sizeX, sizeY, sizeZ);
} 出力
Sum of special triplets = 747
もう1つのより効率的な解決策は、配列XとZを並べ替えることです。次に、配列Yの各要素の特別なトリプレット要件を満たす要素を確認します。
したがって、配列Yのインデックスiにある要素、つまりY[i]の場合。配列X{x1、x2}およびZ {z1、z2}の要素は、Y [i]より小さいため、
値の合計
S = (x1+Y[i])(Y[i]+z1) + (x1+Y[i])(Y[i]+z2) + (x2+Y[i])(Y[i]+z1) + (x2+Y[i])(Y[i]+z2) S = (x1+Y[i])(Y[i]+z1+Y[i]+z2) + (x2+Y[i])(Y[i]+z1+Y[i]+z2) S = (2Y[i] + x1 + x2)(2y[i] + z1 + z2)
N=XのY[i]より大きい要素の数
M =Z
のY[i]より大きい要素の数Sx=XのY[i]より大きい要素の合計
Sz =Z
のY[i]より大きい要素の合計S = (N*Y[i] + Sx) * (M*Y[i] + Sz)
例
上記の解決策を説明するプログラム
#include <bits/stdc++.h>
using namespace std;
int tripletSumCalc(int X[], int Y[], int Z[], int prefixSumA[], int prefixSumC[], int sizeA, int sizeB, int sizeC){
int totalSum = 0;
for (int i = 0; i < sizeB; i++) {
int currentElement = Y[i];
int n = upper_bound(X, X + sizeA, currentElement) - X;
int m = upper_bound(Z, Z + sizeC, currentElement) - Z;
if (n == 0 || m == 0)
continue;
totalSum += ((prefixSumA[n - 1] + (n * currentElement)) * (prefixSumC[m - 1] + (m * currentElement)));
}
return totalSum;
}
int* findPrefixSum(int* arr, int n) {
int* prefixSumArr = new int[n];
prefixSumArr[0] = arr[0];
for (int i = 1; i < n; i++)
prefixSumArr[i] = prefixSumArr[i - 1] + arr[i];
return prefixSumArr;
}
int findSpecialTripletSum(int A[], int B[], int C[], int sizeA, int sizeB, int
sizeC){
int specialTripletSum = 0;
sort(A, A + sizeA);
sort(C, C + sizeC);
int* prefixSumA = findPrefixSum(A, sizeA);
int* prefixSumC = findPrefixSum(C, sizeC);
return tripletSumCalc(A, B, C, prefixSumA, prefixSumC, sizeA, sizeB, sizeC);
}
int main() {
int A[] = {5, 9, 4};
int B[] = {8, 6};
int C[] = {7, 1};
int sizeA = sizeof(A) / sizeof(A[0]);
int sizeB = sizeof(B) / sizeof(B[0]);
int sizeC = sizeof(C) / sizeof(C[0]);
cout<<"Sum of special triplets = "<<findSpecialTripletSum(A, B, C, sizeA, sizeB, sizeC);
} 出力
Sum of special triplets = 747
-
C ++の配列内の非反復(個別)要素の合計を検索します
要素が少ない配列Aがあるとします。配列内のすべての異なる要素の合計を見つける必要があります。したがって、A =[5、12、63、5、33、47、12、63]の場合、個別の要素の合計は160になります。重複する要素は、考慮されると単に無視されます。 順序付けされていないセットを使用して、この問題を効率的に解決できます。 1つのforループを実行し、どの値が最初に来るか、そのadd in sum変数をハッシュテーブルに格納し、次回はこの値を使用しないようにします。 例 #include<iostream> #include<unordered_set> using nam
-
C++で2つの配列の合計を同じにする要素スワッピングのペアを見つけます
要素数が異なる2つの配列があるとします。要素のペア(x、y)を見つける必要があります。ここで、xは最初の配列に存在し、yは2番目の配列に存在します。ペアは、これら2つの配列間で要素を交換した後、これら2つの配列の合計が同じになるように選択されます。 最初の配列Aが[4、1、2、2、1、1]を保持し、Bが[3、3、6、3]を保持しているとすると、Aの合計は11、Bの合計は15になります。 (1、3)のようなペアで、これら2つの配列間でこれらの値を交換すると、合計は次のようになります。[4、3、2、2、1、1] =13、[1、3、6、3] =13、それらは同じです。 これを解決するために、