📌  相关文章
📜  计算三元组,以便其中一个数字可以写成另外两个数字的和

📅  最后修改于: 2021-04-22 10:22:34             🧑  作者: Mango

给定一个由N个整数组成的数组A []。任务是找到三元组(i,j,k)的数量,其中i,j,k是索引,并且(1 <= i A_jA_k }至少一个数字可以写为另外两个数字的和。

例子

Input : A[] = {1, 2, 3, 4, 5}
Output : 4
The valid triplets are:
(1, 2, 3), (1, 3, 4), (1, 4, 5), (2, 3, 5)

Input : A[] = {1, 1, 1, 2, 2}
Output : 6

这是一个计数问题。假设f(x)代表数字的频率x在我们的数组中。

存在四种情况:

  1. 这三个数均等于0。方式数= f(0)C3(其中pCq是从p个数中选择q个数的方式数)。
  2. 一个数等于0,另外两个数等于x> 0:f(0)* f(x)C2。
  3. 两个数字等于某个x> 0,第三个数字为2 * x:f(x)C2 * f(2 * x)。
  4. 这三个数字分别是x,y和x + y,0

下面是上述方法的实现:

C++
// C++ program to count Triplets such that at 
// least one of the numbers can be written 
// as sum of the other two 
#include
using namespace std;
  
    // Functoin to count the number of ways 
    // to choose the triples 
    int countWays(int arr[], int n) 
    { 
        // compute the max value in the array 
        // and create frequency array of size 
        // max_val + 1. 
        // We can also use HashMap to store 
        // frequencies. We have used an array 
        // to keep remaining code simple. 
        int max_val = 0; 
        for (int i = 0; i < n; i++) 
            max_val = max(max_val, arr[i]); 
        int freq[max_val + 1]={0}; 
        for (int i = 0; i < n; i++) 
            freq[arr[i]]++; 
  
        int ans = 0; // stores the number of ways 
  
        // Case 1: 0, 0, 0 
        ans += freq[0] * (freq[0] - 1) * (freq[0] - 2) / 6; 
  
        // Case 2: 0, x, x 
        for (int i = 1; i <= max_val; i++) 
            ans += freq[0] * freq[i] * (freq[i] - 1) / 2; 
  
        // Case 3: x, x, 2*x 
        for (int i = 1; 2 * i <= max_val; i++) 
            ans += freq[i] * (freq[i] - 1) / 2 * freq[2 * i]; 
  
        // Case 4: x, y, x + y 
        // iterate through all pairs (x, y) 
        for (int i = 1; i <= max_val; i++) { 
            for (int j = i + 1; i + j <= max_val; j++) 
                ans += freq[i] * freq[j] * freq[i + j]; 
        } 
  
        return ans; 
    } 
  
    // Driver code 
    int main()
    { 
        int arr[]={ 1, 2, 3, 4, 5 }; 
        int n = sizeof(arr)/sizeof(int); 
        cout<<(countWays(arr, n)); 
        return 0;
    } 
  
//contributed by Arnab Kundu


Java
// Java program to count Triplets such that at
// least one of the numbers can be written
// as a sum of the other two
  
class GFG {
  
    // Function to count the number of ways
    // to choose the triples
    static int countWays(int[] arr, int n)
    {
        // compute the max value in the array
        // and create frequency array of size
        // max_val + 1.
        // We can also use HashMap to store
        // frequencies. We have used an array
        // to keep remaining code simple.
        int max_val = 0;
        for (int i = 0; i < n; i++)
            max_val = Math.max(max_val, arr[i]);
        int[] freq = new int[max_val + 1];
        for (int i = 0; i < n; i++)
            freq[arr[i]]++;
  
        int ans = 0; // stores the number of ways
  
        // Case 1: 0, 0, 0
        ans += freq[0] * (freq[0] - 1) * (freq[0] - 2) / 6;
  
        // Case 2: 0, x, x
        for (int i = 1; i <= max_val; i++)
            ans += freq[0] * freq[i] * (freq[i] - 1) / 2;
  
        // Case 3: x, x, 2*x
        for (int i = 1; 2 * i <= max_val; i++)
            ans += freq[i] * (freq[i] - 1) / 2 * freq[2 * i];
  
        // Case 4: x, y, x + y
        // iterate through all pairs (x, y)
        for (int i = 1; i <= max_val; i++) {
            for (int j = i + 1; i + j <= max_val; j++)
                ans += freq[i] * freq[j] * freq[i + j];
        }
  
        return ans;
    }
  
    // Driver code
    public static void main(String[] args)
    {
        int[] arr = new int[] { 1, 2, 3, 4, 5 };
        int n = arr.length;
        System.out.println(countWays(arr, n));
    }
}


Python3
# Python3 program to count Triplets such 
# that at least one of the numbers can be 
# written as sum of the other two 
import math as mt
  
# Functoin to count the number of ways 
# to choose the triples 
def countWays(arr, n): 
  
    # compute the max value in the array 
    # and create frequency array of size 
    # max_val + 1. 
    # We can also use HashMap to store 
    # frequencies. We have used an array 
    # to keep remaining code simple. 
    max_val = 0
    for i in range(n): 
        max_val = max(max_val, arr[i])
  
    freq = [0 for i in range(max_val + 1)] 
  
    for i in range(n): 
        freq[arr[i]] += 1
  
    ans = 0 # stores the number of ways 
  
    # Case 1: 0, 0, 0 
    ans += (freq[0] * (freq[0] - 1) * 
           (freq[0] - 2) // 6)
  
    # Case 2: 0, x, x 
    for i in range(1, max_val + 1): 
        ans += (freq[0] * freq[i] *
               (freq[i] - 1) // 2)
  
    # Case 3: x, x, 2*x 
    for i in range(1, (max_val + 1) // 2): 
        ans += (freq[i] *
               (freq[i] - 1) // 2 * freq[2 * i]) 
  
    # Case 4: x, y, x + y 
    # iterate through all pairs (x, y) 
    for i in range(1, max_val + 1): 
        for j in range(i + 1, max_val - i + 1): 
            ans += freq[i] * freq[j] * freq[i + j] 
  
    return ans 
  
# Driver code 
arr = [ 1, 2, 3, 4, 5]
n = len(arr)
print(countWays(arr, n)) 
  
# This code is contributed by
# mohit kumar 29


C#
// C# program to count Triplets 
// such that at least one of the 
// numbers can be written as sum 
// of the other two
using System;
  
class GFG
{
  
// Function to count the number 
// of ways to choose the triples
static int countWays(int[] arr, int n)
{
    // compute the max value in the array
    // and create frequency array of size
    // max_val + 1.
    // We can also use HashMap to store
    // frequencies. We have used an array
    // to keep remaining code simple.
    int max_val = 0;
    for (int i = 0; i < n; i++)
        max_val = Math.Max(max_val, arr[i]);
          
    int[] freq = new int[max_val + 1];
    for (int i = 0; i < n; i++)
        freq[arr[i]]++;
  
    int ans = 0; // stores the number of ways
  
    // Case 1: 0, 0, 0
    ans += freq[0] * (freq[0] - 1) * 
                     (freq[0] - 2) / 6;
  
    // Case 2: 0, x, x
    for (int i = 1; i <= max_val; i++)
        ans += freq[0] * freq[i] * 
                        (freq[i] - 1) / 2;
  
    // Case 3: x, x, 2*x
    for (int i = 1; 
             2 * i <= max_val; i++)
        ans += freq[i] * (freq[i] - 1) / 
                      2 * freq[2 * i];
  
    // Case 4: x, y, x + y
    // iterate through all pairs (x, y)
    for (int i = 1; i <= max_val; i++)
    {
        for (int j = i + 1; 
                 i + j <= max_val; j++)
            ans += freq[i] * freq[j] * 
                             freq[i + j];
    }
  
    return ans;
}
  
// Driver code
public static void Main()
{
    int[] arr = { 1, 2, 3, 4, 5 };
    int n = arr.Length;
    Console.WriteLine(countWays(arr, n));
}
}
  
// This code is contributed by shs..


PHP


输出:
4