具有来自 3 个数组的元素的特殊三元组的总和
给定三个数组 A、B 和 C,任务是找到所有特殊三元组的值的总和。一个特殊的三元组被定义为一个三元组 (X, Y, Z),其中条件:
X ≤ Y 和 Z ≤ Y始终成立。每个三元组 (X, Y, Z) 的值由下式给出:
f(X, Y, Z) = (X + Y) * (Y + Z)
注意:如果三元组不是“特殊的”,则对于该特定的三元组,f(x, y, z) = 0。
例子:
Input : A = {1, 4, 5}, B = {2, 3}, C = {2, 1, 3}
Output : 81
Explanation
The special triplets and their values are given below
Triplet f(x, y, z) = (x + y) * (y + z)
(1, 2, 2) (1 + 2) * (2 + 2) = 12
(1, 2, 1) (1 + 2) * (2 + 1) = 9
(1, 3, 2) (1 + 3) * (3 + 2) = 20
(1, 3, 1) (1 + 3) * (3 + 1) = 16
(1, 3, 3) (1 + 3) * (3 + 3) = 24
-------------------------------------
Sum = 81
方法 1(蛮力)我们生成所有三元组并检查一个三元组是否是一个特殊的三元组,我们使用 f(x,y,z) 计算三元组的值,其中 (x,y,z) 是一个特殊的三元组,并且将其添加到所有此类特殊三元组的最终总和中
C++
// C++ Program to find sum of values of
// all special triplets
#include
using namespace std;
/* Finding special triplets (x, y, z) where
x belongs to A; y belongs to B and z
belongs to C; p, q and r are size of
A, B and C respectively */
int findSplTripletsSum(int a[], int b[], int c[],
int p, int q, int r)
{
int sum = 0;
for (int i = 0; i < p; i++) {
for (int j = 0; j < q; j++) {
for (int k = 0; k < r; k++) {
// (a[i], b[j], c[k]) is special if
// a[i] <= b[j] and c[k] <= b[j];
if (a[i] <= b[j] && c[k] <= b[j]) {
// calculate the value of this special
// triplet and add sum of all values
// of such triplets
sum += (a[i] + b[j]) * (b[j] + c[k]);
}
}
}
}
return sum;
}
// Driver Code
int main()
{
int A[] = { 1, 4, 5 };
int B[] = { 2, 3 };
int C[] = { 2, 1, 3 };
int p = sizeof(A) / sizeof(A[0]);
int q = sizeof(B) / sizeof(B[0]);
int r = sizeof(C) / sizeof(C[0]);
cout << "Sum of values of all special triplets = "
<< findSplTripletsSum(A, B, C, p, q, r) << endl;
}
Java
// Java Program to find sum of values of
// all special triplets
class GFG
{
/* Finding special triplets (x, y, z) where
x belongs to A; y belongs to B and z
belongs to C; p, q and r are size of
A, B and C respectively */
static int findSplTripletsSum(int a[], int b[], int c[],
int p, int q, int r)
{
int sum = 0;
for (int i = 0; i < p; i++)
{
for (int j = 0; j < q; j++)
{
for (int k = 0; k < r; k++)
{
// (a[i], b[j], c[k]) is special if
// a[i] <= b[j] and c[k] <= b[j];
if (a[i] <= b[j] && c[k] <= b[j])
{
// calculate the value of this special
// triplet and add sum of all values
// of such triplets
sum += (a[i] + b[j]) * (b[j] + c[k]);
}
}
}
}
return sum;
}
// Driver Code
public static void main(String[] args)
{
int A[] = { 1, 4, 5 };
int B[] = { 2, 3 };
int C[] = { 2, 1, 3 };
int p = A.length;
int q = B.length;
int r = C.length;
System.out.print("Sum of values of all special triplets = "
+ findSplTripletsSum(A, B, C, p, q, r) +"\n");
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 Program to find sum of values of
# all special triplets
# Finding special triplets (x, y, z) where
# x belongs to A y belongs to B and z
# belongs to C p, q and r are size of
# A, B and C respectively
def findSplTripletsSum(a, b, c, p, q, r):
summ = 0
for i in range(p):
for j in range(q):
for k in range(r):
# (a[i], b[j], c[k]) is special if
# a[i] <= b[j] and c[k] <= b[j]
if (a[i] <= b[j] and c[k] <= b[j]):
# calculate the value of this special
# triplet and add sum of all values
# of such triplets
summ += (a[i] + b[j]) * (b[j] + c[k])
return summ
# Driver Code
A = [1, 4, 5 ]
B = [2, 3 ]
C = [2, 1, 3 ]
p = len(A)
q = len(B)
r = len(C)
print("Sum of values of all special triplets = ",
findSplTripletsSum(A, B, C, p, q, r))
# This code is contributed by Mohit kumar 29
C#
// C# Program to find sum of values of
// all special triplets
using System;
class GFG
{
/* Finding special triplets (x, y, z) where
x belongs to A; y belongs to B and z
belongs to C; p, q and r are size of
A, B and C respectively */
static int findSplTripletsSum(int []a, int []b, int []c,
int p, int q, int r)
{
int sum = 0;
for (int i = 0; i < p; i++)
{
for (int j = 0; j < q; j++)
{
for (int k = 0; k < r; k++)
{
// (a[i], b[j], c[k]) is special if
// a[i] <= b[j] and c[k] <= b[j];
if (a[i] <= b[j] && c[k] <= b[j])
{
// calculate the value of this special
// triplet and add sum of all values
// of such triplets
sum += (a[i] + b[j]) * (b[j] + c[k]);
}
}
}
}
return sum;
}
// Driver Code
public static void Main(String[] args)
{
int []A = { 1, 4, 5 };
int []B = { 2, 3 };
int []C = { 2, 1, 3 };
int p = A.Length;
int q = B.Length;
int r = C.Length;
Console.Write("Sum of values of all special triplets = "
+ findSplTripletsSum(A, B, C, p, q, r) +"\n");
}
}
// This code is contributed by PrinciRaj1992
Javascript
C++
// C++ Program to find sum of values
// of all special triplets
#include
using namespace std;
/* Utility function for findSplTripletsSum()
finds total sum of values of all special
triplets */
int findSplTripletsSumUtil(int A[], int B[], int C[],
int prefixSumA[], int prefixSumC[],
int p, int q, int r)
{
int totalSum = 0;
// Traverse through whole array B
for (int i = 0; i < q; i++) {
// store current element Bi
int currentElement = B[i];
// n = number of elements in A less than current
// element
int n = upper_bound(A, A + p, currentElement) - A;
// m = number of elements in C less than current
// element
int m = upper_bound(C, C + r, currentElement) - C;
// if there are Elements neither in A nor C which
// are less than or equal to the current element
if (n == 0 || m == 0)
continue;
/* total sum = (n * currentElement + sum of first
n elements in A) + (m * currentElement + sum of
first m elements in C) */
totalSum +=
((prefixSumA[n - 1] + (n * currentElement)) *
(prefixSumC[m - 1] + (m * currentElement)));
}
return totalSum;
}
/* Builds prefix sum array for arr of size n
and returns a pointer to it */
int* buildPrefixSum(int* arr, int n)
{
// Dynamically allocate memory tp Prefix Sum Array
int* prefixSumArr = new int[n];
// building the prefix sum
prefixSumArr[0] = arr[0];
for (int i = 1; i < n; i++)
prefixSumArr[i] = prefixSumArr[i - 1] + arr[i];
return prefixSumArr;
}
/* Wrapper for Finding special triplets (x, y, z)
where x belongs to A; y belongs to B and z
belongs to C; p, q and r are size of
A, B and C respectively */
int findSplTripletsSum(int A[], int B[], int C[],
int p, int q, int r)
{
int specialTripletSum = 0;
// sort arrays A and C
sort(A, A + p);
sort(C, C + r);
// build prefix arrays for A and C
int* prefixSumA = buildPrefixSum(A, p);
int* prefixSumC = buildPrefixSum(C, r);
return findSplTripletsSumUtil(A, B, C,
prefixSumA, prefixSumC, p, q, r);
}
// Driver Code
int main()
{
int A[] = { 1, 4, 5 };
int B[] = { 2, 3 };
int C[] = { 2, 1, 3 };
int p = sizeof(A) / sizeof(A[0]);
int q = sizeof(B) / sizeof(B[0]);
int r = sizeof(C) / sizeof(C[0]);
cout << "Sum of values of all special triplets = "
<< findSplTripletsSum(A, B, C, p, q, r);
}
Java
// Java Program to find sum of values of
// all special triplets
import java.io.*;
import java.util.*;
public class GFG {
/* Finding special triplets (x, y, z)
where x belongs to A; y belongs to B
and z belongs to C; p, q and r are
size of A, B and C respectively */
static int findSplTripletsSum(int []a,
int []b, int []c, int p,
int q, int r)
{
int sum = 0;
for (int i = 0; i < p; i++) {
for (int j = 0; j < q; j++) {
for (int k = 0; k < r; k++)
{
// (a[i], b[j], c[k]) is
// special if a[i] <= b[j]
// and c[k] <= b[j];
if (a[i] <= b[j] &&
c[k] <= b[j])
{
// calculate the value
// of this special
// triplet and add sum
// of all values
// of such triplets
sum += (a[i] + b[j])
* (b[j] + c[k]);
}
}
}
}
return sum;
}
// Driver Code
public static void main(String args[])
{
int []A = { 1, 4, 5 };
int []B = { 2, 3 };
int []C = { 2, 1, 3 };
int p = A.length;
int q = B.length;
int r = C.length;
System.out.print("Sum of values of all"
+ " special triplets = "
+ findSplTripletsSum(A, B, C, p, q, r));
}
}
// This code is contributed by Manish Shaw
// (manishshaw1)
Python3
# Python3 Program to find sum of values of
# all special triplets
# Finding special triplets (x, y, z)
# where x belongs to A; y belongs to B
# and z belongs to C; p, q and r are
# size of A, B and C respectively
def findSplTripletsSum(a, b, c, p, q, r):
sum = 0
for i in range(p):
for j in range(q):
for k in range(r):
# (a[i], b[j], c[k]) is
# special if a[i] <= b[j]
# and c[k] <= b[j];
if(a[i] <= b[j] and c[k] <= b[j]):
# calculate the value
# of this special
# triplet and add sum
# of all values
# of such triplets
sum += (a[i] + b[j]) * (b[j] + c[k])
return sum
# Driver Code
A = [1, 4, 5]
B = [2, 3 ]
C = [2, 1, 3]
p = len(A)
q = len(B)
r = len(C)
print("Sum of values of all","special triplets =",findSplTripletsSum(A, B, C, p, q, r))
# This code is contributed by avanitrachhadiya2155
C#
// C# Program to find sum of values of
// all special triplets
using System;
using System.Collections.Generic;
using System.Linq;
class GFG {
/* Finding special triplets (x, y, z) where
x belongs to A; y belongs to B and z
belongs to C; p, q and r are size of
A, B and C respectively */
static int findSplTripletsSum(int []a, int []b, int []c,
int p, int q, int r)
{
int sum = 0;
for (int i = 0; i < p; i++) {
for (int j = 0; j < q; j++) {
for (int k = 0; k < r; k++) {
// (a[i], b[j], c[k]) is special if
// a[i] <= b[j] and c[k] <= b[j];
if (a[i] <= b[j] && c[k] <= b[j]) {
// calculate the value of this special
// triplet and add sum of all values
// of such triplets
sum += (a[i] + b[j]) * (b[j] + c[k]);
}
}
}
}
return sum;
}
// Driver Code
public static void Main()
{
int []A = { 1, 4, 5 };
int []B = { 2, 3 };
int []C = { 2, 1, 3 };
int p = A.Length;
int q = B.Length;
int r = C.Length;
Console.WriteLine("Sum of values of all special triplets = "
+ findSplTripletsSum(A, B, C, p, q, r));
}
}
// This code is contributed by
// Manish Shaw (manishshaw1)
Javascript
Sum of values of all special triplets = 81
这种方法的时间复杂度为 O(P * Q * R),其中 P、Q 和 R 分别是三个数组 A、B 和 C 的大小。
方法二(高效)
认为,
数组 A 包含元素 {a, b, c, d, e},
数组 B 包含元素 {f, g, h, i} 和
数组 C 包含元素 {j, k, l, m}。
首先,我们对数组 A 和 C 进行排序,以便我们能够找到数组 A 和 C 中小于特定 B i的元素数量,这可以通过对 B i的每个值应用二进制搜索来完成。
假设在特定索引 i 处,数组 B 的元素是 B i 。还假设在我们完成对 A 和 C 的排序之后,我们有属于数组 A 的元素 {a, b, c} 小于或等于 B i和属于数组 C 的元素 {j, k} 也是小于 B i 。
Lets take Bi = Y from here on.
Let, Total Sum of values of all special triplets = S
We Know S = Σ f(x, y, z) for all possible (x, y, z)
Since elements {a, b, c} of Array A and elements {j, k} of array C are less than Y,
the Special Triplets formed consists of triplets formed only using these elements
with Y always being the second element of every possible triplet
All the Special Triplets and their corresponding values are shown below:
Triplet f(x, y, z) = (x + y) * (y + z)
(a, Y, j) (a + Y)(Y + j)
(a, Y, k) (a + Y)(Y + k)
(b, Y, j) (b + Y)(Y + j)
(b, Y, k) (b + Y)(Y + k)
(c, Y, j) (c + Y)(Y + j)
(c, Y, k) (c + Y)(Y + k)
The sum of these triplets is
S = (a + Y)(Y + j) + (a + Y)(Y + k) + (b + Y)(Y + j) + (b + Y)(Y + k)
+ (c + Y)(Y + j) + (c + Y)(Y + k)
Taking (a + X), (b + X) and (c + x) as common terms we have,
S = (a + Y)(Y + j + Y + k) + (b + Y)(Y + j + Y + k) + (c + Y)(Y + j + Y + k)
Taking (2Y + j + k) common from every term,
S = (a + Y + b + Y + c + Y)(2Y + j + k)
∴ S = (3Y + a + b + c)(2Y + j + k)
Thus,
S = (N * Y + S1) * (M * Y + S2)
where,
N = Number of elements in A less than Y,
M = Number of elements in C less than Y,
S1 = Sum of elements in A less than Y and
S2 = Sum of elements in C less than Y
因此,对于 B 中的每个元素,我们可以使用二分搜索在数组 A 和 C 中找到小于它的元素数量,并且可以使用前缀和找到这些元素的总和
C++
// C++ Program to find sum of values
// of all special triplets
#include
using namespace std;
/* Utility function for findSplTripletsSum()
finds total sum of values of all special
triplets */
int findSplTripletsSumUtil(int A[], int B[], int C[],
int prefixSumA[], int prefixSumC[],
int p, int q, int r)
{
int totalSum = 0;
// Traverse through whole array B
for (int i = 0; i < q; i++) {
// store current element Bi
int currentElement = B[i];
// n = number of elements in A less than current
// element
int n = upper_bound(A, A + p, currentElement) - A;
// m = number of elements in C less than current
// element
int m = upper_bound(C, C + r, currentElement) - C;
// if there are Elements neither in A nor C which
// are less than or equal to the current element
if (n == 0 || m == 0)
continue;
/* total sum = (n * currentElement + sum of first
n elements in A) + (m * currentElement + sum of
first m elements in C) */
totalSum +=
((prefixSumA[n - 1] + (n * currentElement)) *
(prefixSumC[m - 1] + (m * currentElement)));
}
return totalSum;
}
/* Builds prefix sum array for arr of size n
and returns a pointer to it */
int* buildPrefixSum(int* arr, int n)
{
// Dynamically allocate memory tp Prefix Sum Array
int* prefixSumArr = new int[n];
// building the prefix sum
prefixSumArr[0] = arr[0];
for (int i = 1; i < n; i++)
prefixSumArr[i] = prefixSumArr[i - 1] + arr[i];
return prefixSumArr;
}
/* Wrapper for Finding special triplets (x, y, z)
where x belongs to A; y belongs to B and z
belongs to C; p, q and r are size of
A, B and C respectively */
int findSplTripletsSum(int A[], int B[], int C[],
int p, int q, int r)
{
int specialTripletSum = 0;
// sort arrays A and C
sort(A, A + p);
sort(C, C + r);
// build prefix arrays for A and C
int* prefixSumA = buildPrefixSum(A, p);
int* prefixSumC = buildPrefixSum(C, r);
return findSplTripletsSumUtil(A, B, C,
prefixSumA, prefixSumC, p, q, r);
}
// Driver Code
int main()
{
int A[] = { 1, 4, 5 };
int B[] = { 2, 3 };
int C[] = { 2, 1, 3 };
int p = sizeof(A) / sizeof(A[0]);
int q = sizeof(B) / sizeof(B[0]);
int r = sizeof(C) / sizeof(C[0]);
cout << "Sum of values of all special triplets = "
<< findSplTripletsSum(A, B, C, p, q, r);
}
Java
// Java Program to find sum of values of
// all special triplets
import java.io.*;
import java.util.*;
public class GFG {
/* Finding special triplets (x, y, z)
where x belongs to A; y belongs to B
and z belongs to C; p, q and r are
size of A, B and C respectively */
static int findSplTripletsSum(int []a,
int []b, int []c, int p,
int q, int r)
{
int sum = 0;
for (int i = 0; i < p; i++) {
for (int j = 0; j < q; j++) {
for (int k = 0; k < r; k++)
{
// (a[i], b[j], c[k]) is
// special if a[i] <= b[j]
// and c[k] <= b[j];
if (a[i] <= b[j] &&
c[k] <= b[j])
{
// calculate the value
// of this special
// triplet and add sum
// of all values
// of such triplets
sum += (a[i] + b[j])
* (b[j] + c[k]);
}
}
}
}
return sum;
}
// Driver Code
public static void main(String args[])
{
int []A = { 1, 4, 5 };
int []B = { 2, 3 };
int []C = { 2, 1, 3 };
int p = A.length;
int q = B.length;
int r = C.length;
System.out.print("Sum of values of all"
+ " special triplets = "
+ findSplTripletsSum(A, B, C, p, q, r));
}
}
// This code is contributed by Manish Shaw
// (manishshaw1)
Python3
# Python3 Program to find sum of values of
# all special triplets
# Finding special triplets (x, y, z)
# where x belongs to A; y belongs to B
# and z belongs to C; p, q and r are
# size of A, B and C respectively
def findSplTripletsSum(a, b, c, p, q, r):
sum = 0
for i in range(p):
for j in range(q):
for k in range(r):
# (a[i], b[j], c[k]) is
# special if a[i] <= b[j]
# and c[k] <= b[j];
if(a[i] <= b[j] and c[k] <= b[j]):
# calculate the value
# of this special
# triplet and add sum
# of all values
# of such triplets
sum += (a[i] + b[j]) * (b[j] + c[k])
return sum
# Driver Code
A = [1, 4, 5]
B = [2, 3 ]
C = [2, 1, 3]
p = len(A)
q = len(B)
r = len(C)
print("Sum of values of all","special triplets =",findSplTripletsSum(A, B, C, p, q, r))
# This code is contributed by avanitrachhadiya2155
C#
// C# Program to find sum of values of
// all special triplets
using System;
using System.Collections.Generic;
using System.Linq;
class GFG {
/* Finding special triplets (x, y, z) where
x belongs to A; y belongs to B and z
belongs to C; p, q and r are size of
A, B and C respectively */
static int findSplTripletsSum(int []a, int []b, int []c,
int p, int q, int r)
{
int sum = 0;
for (int i = 0; i < p; i++) {
for (int j = 0; j < q; j++) {
for (int k = 0; k < r; k++) {
// (a[i], b[j], c[k]) is special if
// a[i] <= b[j] and c[k] <= b[j];
if (a[i] <= b[j] && c[k] <= b[j]) {
// calculate the value of this special
// triplet and add sum of all values
// of such triplets
sum += (a[i] + b[j]) * (b[j] + c[k]);
}
}
}
}
return sum;
}
// Driver Code
public static void Main()
{
int []A = { 1, 4, 5 };
int []B = { 2, 3 };
int []C = { 2, 1, 3 };
int p = A.Length;
int q = B.Length;
int r = C.Length;
Console.WriteLine("Sum of values of all special triplets = "
+ findSplTripletsSum(A, B, C, p, q, r));
}
}
// This code is contributed by
// Manish Shaw (manishshaw1)
Javascript
Sum of values of all special triplets = 81
由于我们需要遍历整个数组 B 并且对于每个元素在数组 A 和 C 中应用二进制搜索,这种方法的时间复杂度是 O(Q * (logP + logR)) 其中 P、Q 和 R 是大小A、B、C 三个数组。