📜  超级丑数(质因数在给定集合中的数)

📅  最后修改于: 2021-09-17 07:19:52             🧑  作者: Mango

超级丑数是所有质因数都在给定质数列表中的正数。给定一个数 n,任务是找到第 n 个超级丑数。
可以假设给定的一组素数已排序。此外,按照惯例,第一个超级丑陋的数字是 1。

例子:

Input  : primes[] = [2, 5]
         n = 5
Output : 8
Super Ugly numbers with given prime factors 
are 1, 2, 4, 5, 8, ...
Fifth Super Ugly number is 8

Input  : primes[] = [2, 3, 5]
         n = 50
Output : 243

Input : primes[] = [3, 5, 7, 11, 13]
        n = 9
Output: 21 

在我们之前的帖子中,我们讨论了丑数。这个问题基本上是Ugly Numbers的扩展。
这个问题的一个简单解决方案是从1开始一个一个地挑选每个数字并找到它的所有素数因子,如果所有素数因子都在给定的素数集合中,则意味着该数字是超级丑陋的。重复这个过程,直到我们得到第 n 个超级丑数。

此问题的有效解决方案类似于丑数的方法 2。这是算法:

  1. k为给定素数数组的大小。
  2. 为超级丑陋的数字声明一个集合。
  3. 将第一个难看的数字(始终为 1)插入集合中。
  4. 用 0 初始化大小为 k 的数组 multiple_of[k] 。该数组的每个元素都是 primes[k] 数组中相应素数的迭代器。
  5. 用素数[k] 初始化nextMultipe[k] 数组。这个数组的行为类似于给定素数[k]数组中每个素数的下一个多个变量,即; nextMultiple[i] = primes[i] * 丑陋的[++multiple_of[i]]。
  6. 现在循环,直到集合中有 n 个元素丑陋。
    一种)。在 nextMultiple[] 数组中找到当前素数倍数中的最小值并将其插入到丑数集合中。
    b)。然后找到这个当前最小值是哪个素数的倍数。
    C)。将迭代器增加 1,即; ++multiple_Of[i],用于当前选定素数的下一个倍数并为其更新 nextMultiple。

下面是上述步骤的实现。

CPP
// C++ program to find n'th Super Ugly number
#include
using namespace std;
 
// Function to get the nth super ugly number
// primes[]       --> given list of primes f size k
// ugly           --> set which holds all super ugly
//                    numbers from 1 to n
// k              --> Size of prime[]
int superUgly(int n, int primes[], int k)
{
    // nextMultiple holds multiples of given primes
    vector nextMultiple(primes, primes+k);
 
    // To store iterators of all primes
    int multiple_Of[k];
    memset(multiple_Of, 0, sizeof(multiple_Of));
 
    // Create a set to store super ugly numbers and
    // store first Super ugly number
    set ugly;
    ugly.insert(1);
 
    // loop until there are total n Super ugly numbers
    // in set
    while (ugly.size() != n)
    {
        // Find minimum element among all current
        // multiples of given prime
        int next_ugly_no = *min_element(nextMultiple.begin(),
                                    nextMultiple.end());
 
        // insert this super ugly number in set
        ugly.insert(next_ugly_no);
 
        // loop to find current minimum is multiple
        // of which prime
        for (int j=0; j  dp[++index[j]]
                set::iterator it = ugly.begin();
                for (int i=1; i<=multiple_Of[j]; i++)
                    it++;
 
                nextMultiple[j] = primes[j] * (*it);
                break;
            }
        }
    }
 
    // n'th super ugly number
    set::iterator it = ugly.end();
    it--;
    return *it;
}
 
/* Driver program to test above functions */
int main()
{
    int primes[] = {2,  5};
    int k = sizeof(primes)/sizeof(primes[0]);
    int n = 5;
    cout << superUgly(n, primes, k);
    return 0;
}


CPP
// C++ program for super ugly number
#include
using namespace std;
//function will return the nth super ugly number
int ugly(int a[], int size, int n){
     
    //n cannot be negative hence return -1 if n is 0 or -ve
    if(n <= 0)
        return -1;
  
    if(n == 1)
        return 1;
     
    // Declare a min heap priority queue
    priority_queue, greater> pq;
     
    // Push all the array elements to priority queue
    for(int i = 0; i < size; i++){
        pq.push(a[i]);
    }
     
    // once count = n we return no
    int count = 1, no;
     
    while(count < n){
        // Get the minimum value from priority_queue
        no = pq.top();
        pq.pop();
         
        // If top of pq is no then don't increment count. This to avoid duplicate counting of same no.
        if(no != pq.top())
        {
            count++;
         
            //Push all the multiples of no. to priority_queue
            for(int i = 0; i < size; i++){
                pq.push(no * a[i]);
            //    cnt+=1;
        }
        }
    }
    // Return nth super ugly number
    return no;
}
 
/* Driver program to test above functions */
int main(){
    int a[3] = {2, 3,5};
    int size = sizeof(a) / sizeof(a[0]);
    cout << ugly(a, size, 10)<


Python3
# Python3 program for super ugly number
 
# function will return the nth super ugly number
def ugly(a, size, n):
 
    # n cannot be negative hence return -1 if n is 0 or -ve
    if(n <= 0):
        return -1
    if(n == 1):
        return 1
 
    # Declare a min heap priority queue
    pq = []
 
    # Push all the array elements to priority queue
    for i  in range(size):
        pq.append(a[i])
 
    # once count = n we return no
    count = 1
    no = 0
    pq = sorted(pq)
 
    while(count < n):
        # sorted(pq)
        # Get the minimum value from priority_queue
        no = pq[0]
        del pq[0]
 
 
        # If top of pq is no then don't increment count.
        # This to avoid duplicate counting of same no.
        if(no != pq[0]):
            count += 1
 
            # Push all the multiples of no. to priority_queue
            for i in range(size):
                pq.append(no * a[i])
            #   cnt+=1
        pq = sorted(pq)
    # Return nth super ugly number
    return no
 
# /* Driver program to test above functions */
if __name__ == '__main__':
    a = [2, 3,5]
    size = len(a)
    print(ugly(a, size, 1000))
 
    # This code is contributed by mohit kumar 29.


Javascript


输出:

8

另一种方法(使用priority_queue)
这里我们使用最小堆priority_queue。
这个想法是推第一个丑陋的不。它是 1 到 priority_queue 中,并且在每次迭代时取priority_queue 的顶部并将该顶部的所有倍数推入priority_queue。
假设 a[] = {2, 3, 5},
所以在第一次迭代 1 是顶部,所以 1 被弹出并且 1 * 2, 1 * 3, 1 * 5 被推送。
在第二次迭代时 min 为 2,因此它被弹出并推送 2 * 2、2 * 3、2 * 5 等等。

CPP

// C++ program for super ugly number
#include
using namespace std;
//function will return the nth super ugly number
int ugly(int a[], int size, int n){
     
    //n cannot be negative hence return -1 if n is 0 or -ve
    if(n <= 0)
        return -1;
  
    if(n == 1)
        return 1;
     
    // Declare a min heap priority queue
    priority_queue, greater> pq;
     
    // Push all the array elements to priority queue
    for(int i = 0; i < size; i++){
        pq.push(a[i]);
    }
     
    // once count = n we return no
    int count = 1, no;
     
    while(count < n){
        // Get the minimum value from priority_queue
        no = pq.top();
        pq.pop();
         
        // If top of pq is no then don't increment count. This to avoid duplicate counting of same no.
        if(no != pq.top())
        {
            count++;
         
            //Push all the multiples of no. to priority_queue
            for(int i = 0; i < size; i++){
                pq.push(no * a[i]);
            //    cnt+=1;
        }
        }
    }
    // Return nth super ugly number
    return no;
}
 
/* Driver program to test above functions */
int main(){
    int a[3] = {2, 3,5};
    int size = sizeof(a) / sizeof(a[0]);
    cout << ugly(a, size, 10)<

蟒蛇3

# Python3 program for super ugly number
 
# function will return the nth super ugly number
def ugly(a, size, n):
 
    # n cannot be negative hence return -1 if n is 0 or -ve
    if(n <= 0):
        return -1
    if(n == 1):
        return 1
 
    # Declare a min heap priority queue
    pq = []
 
    # Push all the array elements to priority queue
    for i  in range(size):
        pq.append(a[i])
 
    # once count = n we return no
    count = 1
    no = 0
    pq = sorted(pq)
 
    while(count < n):
        # sorted(pq)
        # Get the minimum value from priority_queue
        no = pq[0]
        del pq[0]
 
 
        # If top of pq is no then don't increment count.
        # This to avoid duplicate counting of same no.
        if(no != pq[0]):
            count += 1
 
            # Push all the multiples of no. to priority_queue
            for i in range(size):
                pq.append(no * a[i])
            #   cnt+=1
        pq = sorted(pq)
    # Return nth super ugly number
    return no
 
# /* Driver program to test above functions */
if __name__ == '__main__':
    a = [2, 3,5]
    size = len(a)
    print(ugly(a, size, 1000))
 
    # This code is contributed by mohit kumar 29.

Javascript


输出:

51200000

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