📌  相关文章
📜  2或3的大小被3整除的组数

📅  最后修改于: 2021-05-04 11:18:43             🧑  作者: Mango

您会得到N个不同的数字。您的任务是查找可以形成的2或3个组的数量,它们的总和可被3整除。
例子 :

Input  : 1 5 7 2 9 14
Output : 13
The groups of two that can be 
formed are:
(1, 5)
(5, 7)
(1, 2)
(2, 7)
(1, 14)
(7, 14)
The groups of three are:
(1, 5, 9)
(5, 7, 9)
(1, 2, 9)
(2, 7, 9)
(2, 5, 14)
(1, 9, 14)
(7, 9, 14)

Input  : 3 6 9 12
Output : 10
All groups of 2 and 3 are valid.

天真的方法:对于每个数字,我们可以将其与其他每个数字相加,然后查看该总和是否可被3整除。然后存储这些总和,以便我们可以再次将每个数字相加,以检查是否有三个。
时间复杂度:2组为O(N ^ 2),3组为O(N ^ 3)
辅助空间:O(N ^ 2)
最佳方法
如果我们仔细查看每个数字,就会发现存在3种选择:

  1. 该数字可被3整除
  2. 该数字除以3的余数为1
  3. 该数字除以3的余数为2

现在,对于两个被3整除的组,这两个数字都必须属于类别1(两个都可以被3整除),或者一个数字应保留余数1,而另一个应保留余数2。这样,余数加起来到3,使总和被3整除。
要形成一个由三个组成的组,则所有三个数字应给出相同的余数,或者一个应给出余数0,另一个应给出1,最后一个应给出2。
这样,我们不在乎数字本身,而是在乎它们各自的余数。因此,通过将它们分为三类,我们可以使用一个简单的公式找到所有可能的组。
令C1为可被3整除的元素数。
令C2为剩余数为1的元素数。
令C3为剩余2的元素数。

Answer = 
C2 * C3 + C1 * (C1 - 1) / 2    --> Groups of 2
+ C1 * (C1 - 1) * (C1 - 2) / 6 
+ C2 * (C2 - 1) * (C2 - 2) / 6 
+ C3 * (C3 - 1) * (C3 - 2) / 6 --> Groups of 3 
                   with elements of same remainder
+ C1 * C2 * C3 --> Groups of three with all
                         distinct remainders
CPP
// Program to find groups of 2 or 3
// whose sum is divisible by 3
#include 
using namespace std;
 
int numOfCombinations(int arr[], int N)
{
    // Initialize groups to 0
    int C[3] = { 0, 0, 0 };
 
    // Increment group with specified remainder
    for (int i = 0; i < N; ++i)
        ++C[arr[i] % 3];
 
    // Return groups using the formula
    return C[1] * C[2] + C[0] * (C[0] - 1) / 2 + C[0] * (C[0] - 1) * (C[0] - 2) / 6 + C[1] * (C[1] - 1) * (C[1] - 2) / 6 + C[2] * (C[2] - 1) * (C[2] - 2) / 6 + C[0] * C[1] * C[2];
}
 
// Driver Function
int main()
{
    int arr1[6] = { 1, 5, 7, 2, 9, 14 };
    cout << numOfCombinations(arr1, 6) << "\n";
    int arr2[4] = { 3, 6, 9, 12 };
    cout << numOfCombinations(arr2, 4) << "\n";
    return 0;
}


Java
// Program to find groups of 2 or 3
// whose sum is divisible by 3
 
class GFG {
 
    static int numOfCombinations(int arr[], int N)
    {
        // Initialize groups to 0
        int C[] = { 0, 0, 0 };
 
        // Increment group with specified remainder
        for (int i = 0; i < N; ++i)
            ++C[arr[i] % 3];
 
        // Return groups using the formula
        return C[1] * C[2] + C[0] * (C[0] - 1) / 2 + C[0] * (C[0] - 1) * (C[0] - 2) / 6 + C[1] * (C[1] - 1) * (C[1] - 2) / 6 + C[2] * (C[2] - 1) * (C[2] - 2) / 6 + C[0] * C[1] * C[2];
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int arr1[] = { 1, 5, 7, 2, 9, 14 };
        System.out.print(numOfCombinations(arr1, 6) + "\n");
        int arr2[] = { 3, 6, 9, 12 };
        System.out.print(numOfCombinations(arr2, 4) + "\n");
    }
}
 
// This code is contributed by Anant Agarwal.


Python3
# Program to find groups of 2 or 3
# whose sum is divisible by 3
 
def numOfCombinations(arr, N):
    # Initialize groups to 0
    C = [0, 0, 0]
  
    # Increment group with
    # specified remainder
    for i in range(N):
         
        C[arr[i] % 3]= C[arr[i] % 3]+1
  
    # Return groups using the formula
    return (C[1] * C[2] + C[0] * (C[0] - 1) / 2 + C[0] * (C[0] - 1) * (C[0] - 2) / 6 + C[1] * (C[1] - 1) * (C[1] - 2) / 6 + C[2] * (C[2] - 1) * (C[2] - 2) / 6 + C[0] * C[1] * C[2])
 
# Driver code
 
arr1 = [1, 5, 7, 2, 9, 14]
print(int(numOfCombinations(arr1, 6)))
arr2 = [3, 6, 9, 12]
print(int(numOfCombinations(arr2, 4)))
 
 
# This code is contributed
# by Anant Agarwal.


C#
// C# Program to find groups of 2 or
// 3 whose sum is divisible by 3
using System;
 
class GFG {
 
    // Function to find number of combinations
    static int numOfCombinations(int[] arr,
                                 int N)
    {
 
        // Initialize groups to 0
        int[] C = { 0, 0, 0 };
 
        // Increment group with specified remainder
        for (int i = 0; i < N; ++i)
            ++C[arr[i] % 3];
 
        // Return groups using the formula
        return C[1] * C[2] + C[0] * (C[0] - 1) / 2 + C[0] * (C[0] - 1) * (C[0] - 2) / 6 + C[1] * (C[1] - 1) * (C[1] - 2) / 6 + C[2] * (C[2] - 1) * (C[2] - 2) / 6 + C[0] * C[1] * C[2];
    }
 
    // Driver code
    public static void Main()
    {
        int[] arr1 = { 1, 5, 7, 2, 9, 14 };
        Console.WriteLine(numOfCombinations(arr1, 6));
        int[] arr2 = { 3, 6, 9, 12 };
        Console.WriteLine(numOfCombinations(arr2, 4));
    }
}
 
// This code is contributed by vt_m.


PHP


Javascript


输出 :

13
10