📌  相关文章
📜  数组中大小为3的子序列,其和可被m整除

📅  最后修改于: 2021-04-29 15:02:50             🧑  作者: Mango

给定数组A [](1 <= A _i <= 10 ^9 )大小N(1 <= N <= 10 ^5 ),找到长度为3的子序列,其总和可被M(1 <= M <= 10 ^3 )。
例子:

Input  : A[] = {1, 2, 4, 3}
           M = 3 
Output : 2
Explanation : We can choose two such 
subsequence of length 3 such that its 
sum is divisible by 3 -> {1, 2, 3} ans 
{2, 4, 3}

蛮力法:我们使用3个嵌套循环遍历所有长度为3的子序列,以计算所有满足给定条件的子序列。

在这里,蛮力解决方案将在O(N ^3 )

C++
// Brute Force Implementation (Time Complexity :
// O(N^3)) C++ program to find count of subsequences of size
// three divisible by M.
#include 
  
using namespace std;
  
int coutSubSeq(int A[], int N, int M)
{
    int sum = 0;
    int ans = 0;
  
    // Three nested loop to find all the sub 
    // sequences of length three in the given 
    // array A[].
    for (int i = 0; i < N; i++) {
        for (int j = i + 1; j < N; j++) {
            for (int k = j + 1; k < N; k++) {
                sum = A[i] + A[j] + A[k];
  
                // checking if the sum of the chosen
                // three number is divisible by m.
                if (sum % M == 0)
                    ans++;
            }
        }
    }
    return ans;
}
  
// Driver code
int main()
{
    int M = 3;
    int A[] = { 1, 2, 4, 3 };
    int N = sizeof(A)/sizeof(A[0]);
    cout << coutSubSeq(A, N, M);
    return 0;
}


Java
// Java program to find count of
// subsequences of size three
// divisible by M.
import java.io.*;
  
class GFG {
      
    static int coutSubSeq(int A[], int N,
                                   int M)
    {
        int sum = 0;
        int ans = 0;
       
        // Three nested loop to find all the
        // sub sequences of length three in
        // the given array A[].
        for (int i = 0; i < N; i++) {
            for (int j = i + 1; j < N; j++) {
                for (int k = j + 1; k < N; k++) {
                    sum = A[i] + A[j] + A[k];
       
                    // checking if the sum of the
                    // chosen three number is 
                    // divisible by m.
                    if (sum % M == 0)
                        ans++;
                }
            }
        }
        return ans;
    }
       
    // Driver code
    public static void main(String args[])
    {
        int M = 3;
        int A[] = { 1, 2, 4, 3 };
        int N = A.length;
        System.out.println(coutSubSeq(A, N, M));
    }
}
  
/*This code is contributed by Nikita Tiwari*/


Python
# Python program to find count of
# subsequences of size three 
# divisible by M.
  
def coutSubSeq(A, N,M) :
    sum = 0
    ans = 0
   
    # Three nested loop to find all the
    # sub sequences of length three in 
    # the given array A[].
    for i in range(0, N) :
        for j in range(i + 1, N) :
            for k in range(j + 1, N) :
                sum = A[i] + A[j] + A[k]
   
                # checking if the sum of 
                # the chosen three number
                # is divisible by m.
                if (sum % M == 0) :
                    ans = ans + 1
    return ans
      
# Driver code
M = 3
A = [ 1, 2, 4, 3 ]
N = len(A)
print coutSubSeq(A, N, M)
  
# This code is contributed by Nikita Tiwari.


C#
// C# program to find count of subsequences 
// of size three divisible by M.
using System;
  
class GFG {
      
    static int coutSubSeq(int[] A, int N, int M)
    {
        int sum = 0;
        int ans = 0;
      
        // Three nested loop to find all the
        // sub sequences of length three in
        // the given array A[].
        for (int i = 0; i < N; i++) {
            for (int j = i + 1; j < N; j++) {
                for (int k = j + 1; k < N; k++)
                {
                    sum = A[i] + A[j] + A[k];
      
                    // checking if the sum of
                    // the chosen three number
                    // is divisible by m.
                    if (sum % M == 0)
                        ans++;
                }
            }
        }
        return ans;
    }
      
    // Driver code
    public static void Main()
    {
        int M = 3;
        int []A = { 1, 2, 4, 3 };
        int N = A.Length;
        Console.WriteLine(coutSubSeq(A, N, M));
    }
}
  
// This code is contributed by anuj_67.


PHP


C++
// O(M^2) time complexity C++ program to find 
// count of subsequences of size three
// divisible by M.
#include 
  
using namespace std;
  
int countSubSeq(int A[], int N, int M)
{
    int ans = 0;
  
    // Storing frequencies of all remainders
    // when divided by M.
    int h[M] = { 0 };
    for (int i = 0; i < N; i++) {
        A[i] = A[i] % M;
        h[A[i]]++;
    }
  
    for (int i = 0; i < M; i++) {
        for (int j = i; j < M; j++) {
  
            // including i and j in the sum rem
            // calculate the remainder required 
            // to make the sum divisible by M
            int rem = (M - (i + j) % M) % M;
  
            // if the required number is less than
            // j, we skip as we have already calculated 
            // for that value before. As j here starts 
            // with i and rem is less than j.
            if (rem < j)
                continue;
  
            // if satisfies the first case.
            if (i == j && rem == j)
                ans += h[i] * (h[i] - 1) * (h[i] - 2) / 6;
  
            // if satisfies the second case
            else if (i == j)
                ans += h[i] * (h[i] - 1) * h[rem] / 2;
  
            else if (i == rem)
                ans += h[i] * (h[i] - 1) * h[j] / 2;
            else if (rem == j)
                ans += h[j] * (h[j] - 1) * h[i] / 2;
  
            // if satisfies the third case
            else
                ans = ans + h[i] * h[j] * h[rem];
        }
    }
    return ans;
}
  
// Driver code
int main()
{   
    int M = 3;
    int A[] = { 1, 2, 4, 3 };
    int N = sizeof(A)/sizeof(A[0]);
    cout << countSubSeq(A, N, M);
    return 0;
}


Java
// Java program to find count of 
// subsequences of size three
// divisible by M.
import java.io.*;
import java.util.Arrays;
  
class GFG {
  
    static int countSubSeq(int A[], int N, int M)
    {
        int ans = 0;
       
        // Storing frequencies of all 
        // remainders when divided by M.
        int h[] = new int[M];
        Arrays.fill(h,0);
        for (int i = 0; i < N; i++) {
            A[i] = A[i] % M;
            h[A[i]]++;
        }
       
        for (int i = 0; i < M; i++) {
            for (int j = i; j < M; j++) {
       
                // including i and j in the sum
                // rem calculate the remainder
                // required to make the sum
                // divisible by M
                int rem = (M - (i + j) % M) % M;
       
                // if the required number is 
                // less than j, we skip as we 
                // have already calculated for
                // that value before. As j here
                // starts with i and rem is 
                // less than j.
                if (rem < j)
                    continue;
       
                // if satisfies the first case.
                if (i == j && rem == j)
                    ans += h[i] * (h[i] - 1) *
                           (h[i] - 2) / 6;
       
                // if satisfies the second case
                else if (i == j)
                    ans += h[i] * (h[i] - 1) *
                           h[rem] / 2;
       
                else if (i == rem)
                    ans += h[i] * (h[i] - 1) *
                           h[j] / 2;
                else if (rem == j)
                    ans += h[j] * (h[j] - 1) *
                           h[i] / 2;
       
                // if satisfies the third case
                else
                    ans = ans + h[i] * h[j] *
                          h[rem];
            }
        }
        return ans;
    }
       
    // Driver code
    public static void main(String args[])
    {
        int M = 3;
        int A[] = { 1, 2, 4, 3 };
        int N = A.length;
        System.out.println(countSubSeq(A, N, M));
    }
}
  
/*This code is contributed by Nikita Tiwari*/


Python
# Python program to find count of
# subsequences of size three
# divisible by M.
  
def countSubSeq(A, N, M) :
    ans = 0
      
    # Storing frequencies of all
    # remainders when divided by M.
    h = [0] * M
    for i in range(0,N) :
        A[i] = A[i] % M
        h[A[i]] = h[A[i]] + 1
      
    for i in range(0,M) :
        for j in range(i,M) :
              
            # including i and j in the sum
            # rem calculate the remainder
            # required to make the sum
            # divisible by M
            rem = (M - (i + j) % M) % M
              
            # if the required number is 
            # less than j, we skip as we 
            # have already calculated for
            # that value before. As j here
            # starts with i and rem is 
            # less than j.
            if (rem < j) :
                continue
                  
            # if satisfies the first case.
            if (i == j and rem == j) :
                ans = ans + h[i] * (h[i] - 1) * (h[i] - 2) / 6
                  
                  
            # if satisfies the second case
            elif (i == j) :
                ans = ans +( h[i] * (h[i] - 1) * h[rem] / 2)
       
            elif (i == rem) :
                ans = ans + h[i] * (h[i] - 1) * h[j] / 2
            elif (rem == j) :
                ans = ans + h[j] * (h[j] - 1) * h[i] / 2
       
            # if satisfies the third case
            else :
                ans = ans + h[i] * h[j] * h[rem]
              
        return ans
          
# Driver code
M = 3;
A = [ 1, 2, 4, 3 ]
N = len(A)
print(countSubSeq(A, N, M))
  
# This code is contributed by Nikita Tiwari.


C#
// C# program to find count of subsequences of
// size three divisible by M.
using System;
  
class GFG {
  
    static int countSubSeq(int []A, int N, int M)
    {
        int ans = 0;
      
        // Storing frequencies of all 
        // remainders when divided by M.
        int []h = new int[M];
      
        for (int i = 0; i < N; i++) {
            A[i] = A[i] % M;
            h[A[i]]++;
        }
      
        for (int i = 0; i < M; i++) {
            for (int j = i; j < M; j++) {
      
                // including i and j in the sum
                // rem calculate the remainder
                // required to make the sum
                // divisible by M
                int rem = (M - (i + j) % M) % M;
      
                // if the required number is 
                // less than j, we skip as we 
                // have already calculated for
                // that value before. As j here
                // starts with i and rem is 
                // less than j.
                if (rem < j)
                    continue;
      
                // if satisfies the first case.
                if (i == j && rem == j)
                    ans += h[i] * (h[i] - 1) *
                                (h[i] - 2) / 6;
      
                // if satisfies the second case
                else if (i == j)
                    ans += h[i] * (h[i] - 1) *
                                    h[rem] / 2;
      
                else if (i == rem)
                    ans += h[i] * (h[i] - 1) *
                                     h[j] / 2;
                else if (rem == j)
                    ans += h[j] * (h[j] - 1) *
                                     h[i] / 2;
      
                // if satisfies the third case
                else
                    ans = ans + h[i] * h[j] *
                                      h[rem];
            }
        }
        return ans;
    }
      
    // Driver code
    public static void Main()
    {
        int M = 3;
        int []A = { 1, 2, 4, 3 };
        int N = A.Length;
        Console.WriteLine(countSubSeq(A, N, M));
    }
}
  
// This code is contributed by anuj_67.


PHP


输出:

2

第二种方法(对于小M而言是有效的):上面的实现花费大量时间。因此,我们需要一种更好的方法来解决此问题。在这里,我们将使用索引映射(哈希技术)来解决该问题。由于我们需要检查所选的三个数字的总和是否可被M整除,因此我们将每个值存储在模M下。我们使用频率数组通过索引映射技术存储每个元素的出现次数。

可能发生三种情况:
首先,如果一个数字的三次可被M整除,则我们将添加{{N}\choose{3}}回答N是那个数字的频率。
其次,如果某个数字A的两倍与总和B的乘积可被M整除,则我们将添加{{Freq[A]}\choose{2}} *答案的频率[B]。
第三,如果所有的数字A,B,C的总和等于S,而S被M整除,那么我们将在答案中加上Freq [A] * Freq [B] * Freq [C]。

通过这种方法,我们可以解决O(M ^2 ),可以在指定时间内执行。

C++

// O(M^2) time complexity C++ program to find 
// count of subsequences of size three
// divisible by M.
#include 
  
using namespace std;
  
int countSubSeq(int A[], int N, int M)
{
    int ans = 0;
  
    // Storing frequencies of all remainders
    // when divided by M.
    int h[M] = { 0 };
    for (int i = 0; i < N; i++) {
        A[i] = A[i] % M;
        h[A[i]]++;
    }
  
    for (int i = 0; i < M; i++) {
        for (int j = i; j < M; j++) {
  
            // including i and j in the sum rem
            // calculate the remainder required 
            // to make the sum divisible by M
            int rem = (M - (i + j) % M) % M;
  
            // if the required number is less than
            // j, we skip as we have already calculated 
            // for that value before. As j here starts 
            // with i and rem is less than j.
            if (rem < j)
                continue;
  
            // if satisfies the first case.
            if (i == j && rem == j)
                ans += h[i] * (h[i] - 1) * (h[i] - 2) / 6;
  
            // if satisfies the second case
            else if (i == j)
                ans += h[i] * (h[i] - 1) * h[rem] / 2;
  
            else if (i == rem)
                ans += h[i] * (h[i] - 1) * h[j] / 2;
            else if (rem == j)
                ans += h[j] * (h[j] - 1) * h[i] / 2;
  
            // if satisfies the third case
            else
                ans = ans + h[i] * h[j] * h[rem];
        }
    }
    return ans;
}
  
// Driver code
int main()
{   
    int M = 3;
    int A[] = { 1, 2, 4, 3 };
    int N = sizeof(A)/sizeof(A[0]);
    cout << countSubSeq(A, N, M);
    return 0;
}

Java

// Java program to find count of 
// subsequences of size three
// divisible by M.
import java.io.*;
import java.util.Arrays;
  
class GFG {
  
    static int countSubSeq(int A[], int N, int M)
    {
        int ans = 0;
       
        // Storing frequencies of all 
        // remainders when divided by M.
        int h[] = new int[M];
        Arrays.fill(h,0);
        for (int i = 0; i < N; i++) {
            A[i] = A[i] % M;
            h[A[i]]++;
        }
       
        for (int i = 0; i < M; i++) {
            for (int j = i; j < M; j++) {
       
                // including i and j in the sum
                // rem calculate the remainder
                // required to make the sum
                // divisible by M
                int rem = (M - (i + j) % M) % M;
       
                // if the required number is 
                // less than j, we skip as we 
                // have already calculated for
                // that value before. As j here
                // starts with i and rem is 
                // less than j.
                if (rem < j)
                    continue;
       
                // if satisfies the first case.
                if (i == j && rem == j)
                    ans += h[i] * (h[i] - 1) *
                           (h[i] - 2) / 6;
       
                // if satisfies the second case
                else if (i == j)
                    ans += h[i] * (h[i] - 1) *
                           h[rem] / 2;
       
                else if (i == rem)
                    ans += h[i] * (h[i] - 1) *
                           h[j] / 2;
                else if (rem == j)
                    ans += h[j] * (h[j] - 1) *
                           h[i] / 2;
       
                // if satisfies the third case
                else
                    ans = ans + h[i] * h[j] *
                          h[rem];
            }
        }
        return ans;
    }
       
    // Driver code
    public static void main(String args[])
    {
        int M = 3;
        int A[] = { 1, 2, 4, 3 };
        int N = A.length;
        System.out.println(countSubSeq(A, N, M));
    }
}
  
/*This code is contributed by Nikita Tiwari*/

Python

# Python program to find count of
# subsequences of size three
# divisible by M.
  
def countSubSeq(A, N, M) :
    ans = 0
      
    # Storing frequencies of all
    # remainders when divided by M.
    h = [0] * M
    for i in range(0,N) :
        A[i] = A[i] % M
        h[A[i]] = h[A[i]] + 1
      
    for i in range(0,M) :
        for j in range(i,M) :
              
            # including i and j in the sum
            # rem calculate the remainder
            # required to make the sum
            # divisible by M
            rem = (M - (i + j) % M) % M
              
            # if the required number is 
            # less than j, we skip as we 
            # have already calculated for
            # that value before. As j here
            # starts with i and rem is 
            # less than j.
            if (rem < j) :
                continue
                  
            # if satisfies the first case.
            if (i == j and rem == j) :
                ans = ans + h[i] * (h[i] - 1) * (h[i] - 2) / 6
                  
                  
            # if satisfies the second case
            elif (i == j) :
                ans = ans +( h[i] * (h[i] - 1) * h[rem] / 2)
       
            elif (i == rem) :
                ans = ans + h[i] * (h[i] - 1) * h[j] / 2
            elif (rem == j) :
                ans = ans + h[j] * (h[j] - 1) * h[i] / 2
       
            # if satisfies the third case
            else :
                ans = ans + h[i] * h[j] * h[rem]
              
        return ans
          
# Driver code
M = 3;
A = [ 1, 2, 4, 3 ]
N = len(A)
print(countSubSeq(A, N, M))
  
# This code is contributed by Nikita Tiwari.

C#

// C# program to find count of subsequences of
// size three divisible by M.
using System;
  
class GFG {
  
    static int countSubSeq(int []A, int N, int M)
    {
        int ans = 0;
      
        // Storing frequencies of all 
        // remainders when divided by M.
        int []h = new int[M];
      
        for (int i = 0; i < N; i++) {
            A[i] = A[i] % M;
            h[A[i]]++;
        }
      
        for (int i = 0; i < M; i++) {
            for (int j = i; j < M; j++) {
      
                // including i and j in the sum
                // rem calculate the remainder
                // required to make the sum
                // divisible by M
                int rem = (M - (i + j) % M) % M;
      
                // if the required number is 
                // less than j, we skip as we 
                // have already calculated for
                // that value before. As j here
                // starts with i and rem is 
                // less than j.
                if (rem < j)
                    continue;
      
                // if satisfies the first case.
                if (i == j && rem == j)
                    ans += h[i] * (h[i] - 1) *
                                (h[i] - 2) / 6;
      
                // if satisfies the second case
                else if (i == j)
                    ans += h[i] * (h[i] - 1) *
                                    h[rem] / 2;
      
                else if (i == rem)
                    ans += h[i] * (h[i] - 1) *
                                     h[j] / 2;
                else if (rem == j)
                    ans += h[j] * (h[j] - 1) *
                                     h[i] / 2;
      
                // if satisfies the third case
                else
                    ans = ans + h[i] * h[j] *
                                      h[rem];
            }
        }
        return ans;
    }
      
    // Driver code
    public static void Main()
    {
        int M = 3;
        int []A = { 1, 2, 4, 3 };
        int N = A.Length;
        Console.WriteLine(countSubSeq(A, N, M));
    }
}
  
// This code is contributed by anuj_67.

的PHP


输出:

2