📜  乘积为唯一素数倍数的子集计数

📅  最后修改于: 2021-10-26 06:37:05             🧑  作者: Mango

给定一个大小为N的数组arr[] 任务是计算乘积等于P1×P2×P3×……..×Pk的非空子集的数量,其中P1, P2, P3, …….Pk是不同的素数。

例子:

方法:主要思想是找到仅是不同素数的乘积的数字,并调用递归将它们包含在子集中或不包含在子集中。此外,当且仅当添加元素后整个子集的 GCD 为 1 时,才将元素添加到子集中。 请按照以下步骤解决问题:

  • 初始化一个 dict,比如Freq,以存储数组元素的频率。
  • 初始化一个数组,比如说, Unique[]并存储所有那些仅是不同素数的乘积的元素。
  • 调用递归函数,比如Countprime(pos, curSubset)来计算所有这些子集。
  • 基本情况:如果pos等于唯一数组的大小
    • 如果curSubset为空,则返回0
    • 否则,返回curSubset的每个元素的频率乘积
  • 检查pos处的元素是否可以在当前子集中被采用
    • 如果采用,则调用递归函数作为countPrime(pos+1, curSubset)countPrime(pos+1, curSubset+[unique[pos]]) 的总和。
    • 否则,调用countPrime(pos+1, curSubset)。
  • 打印从函数返回的答案

下面是上述方法的实现:

Python3
# Python program for the above approach
  
# Importing the module
from math import gcd, sqrt
  
# Function to check number has
# distinct prime
def checkDistinctPrime(n):
    original = n
    product = 1
  
    # While N has factors of
    # two
    if (n % 2 == 0):
        product *= 2
        while (n % 2 == 0):
            n = n//2
      
    # Traversing till sqrt(N)
    for i in range(3, int(sqrt(n)), 2):
        
        # If N has a factor of i
        if (n % i == 0):
            product = product * i
              
            # While N has a factor 
            # of i
            while (n % i == 0):
                n = n//i
  
    # Covering case, N is Prime
    if (n > 2):
        product = product * n
  
    return product == original
  
  
# Function to check wheather num 
# can be added to the subset
def check(pos, subset, unique):
    for num in subset:
        if gcd(num, unique[pos]) != 1:
            return False
    return True
  
  
# Recursive Function to count subset
def countPrime(pos, currSubset, unique, frequency):
  
    # Base Case
    if pos == len(unique):
          
        # If currSubset is empty
        if not currSubset:
            return 0
  
        count = 1
        for element in currSubset:
            count *= frequency[element]
        return count
  
    # If Unique[pos] can be added to 
    # the Subset
    if check(pos, currSubset, unique):
        return countPrime(pos + 1, currSubset, \
                          unique, frequency)\
             + countPrime(pos + 1, currSubset+[unique[pos]], \
                          unique, frequency)
    else:
        return countPrime(pos + 1, currSubset, \
                          unique, frequency)
    
# Function to count the subsets
def countSubsets(arr, N):
    
    # Initialize unique
    unique = set()
    for element in arr:
        # Check it is a product of
        # distinct primes
        if checkDistinctPrime(element):
            unique.add(element)
  
    unique = list(unique)
      
    # Count frequency of unique element
    frequency = dict()
    for element in unique:
        frequency[element] = arr.count(element)
  
    # Function Call
    ans = countPrime(0, [], unique, frequency)
    return ans
  
# Driver Code
if __name__ == "__main__":
  
    # Given Input
    arr = [2, 4, 7, 10]
    N = len(arr)
      
    # Function Call
    ans = countSubsets(arr, N)
    print(ans)


输出
5

时间复杂度: O(2 N )
辅助空间: O(N)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程