将N转换为M的每个步骤中要添加的N的质因数个数


在这个问题中,我们将通过在每次操作中将N的一个质因数加到自身并更新它来将数字N转换为M。

我们将使用广度优先搜索算法来解决这个问题。我们将找到每个更新后的N的质因数,并在将其添加到N的质因数后将其插入队列。此外,我们还将定义函数来查找特定数字的最小质因数。

问题陈述 - 我们给出了N和M整数的值。我们需要计算将N转换为M所需的最小操作次数。在每次操作中,我们需要取更新后的N值的其中一个质因数并将其加到N上。如果可以将N转换为M,则打印最小操作次数。否则,打印-1。

示例

输入

N = 8, M = 12;

输出

2

解释 

  • 在第一次操作中,取“2”(8的质因数)并将其加到8上。因此,N变为10。

  • 在接下来的操作中,再次将2加到10上。

输入

N = 7, M = 13;

输出

-1

解释 - 7和13都是质数。因此,无法将N转换为M。

输入

N = 7, M = 14;

输出

1

解释 - 7是7的质因数。因此,当我们将7加到7上时,我们可以在一次操作中得到14。

方法

在这种方法中,我们将使用筛法算法计算2到100009范围内每个数字的最小质因数。

之后,我们将使用队列数据结构来维护添加质因数后更新的N值,并将其与达到更新值的所需操作次数映射。

例如,我们希望将3变成9。

  • 第一步,我们将3与距离0一起添加到队列中。

  • 之后,我们将得到3的质因数,即{3}。

  • 下一步,我们将6(3 + 3)与距离1一起添加到队列中。

  • 之后,我们将找到6的质因数,即{2, 3}。

  • 因此,我们将{8, 2}(6+2, 1+1)和{9, 2}(6 + 3, 1 + 1)对插入队列。这里,对的第一个元素是更新后的值,对的第二个元素是递增1后的距离。

  • 之后,我们从队列中获取{8, 2}对。8的质因数是{2}。因此,我们将{10, 3}插入队列。

  • 接下来,我们从队列中获取{9, 2}。这里,9等于M。因此,我们打印2作为答案。

算法

步骤1 - 定义大小为100009的prime[]数组以存储每个数字的最小质因数。

步骤2 - 之后,定义getPrimeNumbers()函数来查找每个数字的最小质因数。

步骤2.1 - 将所有prime[]数组元素初始化为-1。

步骤2.2 - 从2开始遍历数组,并遍历直到p*p小于100009。此外,使用嵌套循环从第p个索引开始更新每个第p个索引。

步骤2.3 - 在嵌套循环中,如果prime[q]为-1,则将其更新为p值。

步骤3 - 定义getPrimeFactors()函数来查找特定值的全部质因数。

步骤3.1 - 定义'p_factors'集合以存储质因数。

步骤3.2 - 遍历给定数字,直到其值小于1。

步骤3.3 - 在循环中,将prime[num]插入p_factors集合中,它是数字的最小质因数。

步骤3.4 - 将数字除以最小质因数。

步骤3.5 - 当循环完成所有迭代时,返回p_factors集合。

步骤4 - 在findMinimumSteps()函数中,定义队列以存储更新后的N值对和所需操作次数。并将{n, 0}对插入队列。

步骤5 - 迭代直到队列变空。

步骤5.1 - 从队列中弹出第一对。此外,将对的第一个元素存储在'temp'变量中,并将对的第二个元素存储在'dist'变量中。

步骤5.2 - 如果temp等于m,则返回'dist'值。

步骤5.3 - 如果'temp'大于m,则中断循环。

步骤5.4 - 执行getPrimeFactors()函数以获取'temp'的质因数,并将它们存储到'p_factors'集合中。

步骤5.5 - 现在,遍历p_factors集合的每个元素。

步骤5.5.1 - 将{temp + p, dist + 1}对插入队列以供每个质因数使用。

步骤6 - 在函数末尾返回-1。

示例

#include <bits/stdc++.h>
using namespace std;
// To store all prime numbers
int prime[100009];
// To find prime numbers
void getPrimeNumbers() {
    // Initializing with -1
    memset(prime, -1, 100005);
    // Pre-computing smallest prime factor
    for (int p = 2; p * p <= 100005; p++) {
        for (int q = p; q <= 100005; q += p) {
            if (prime[q] == -1) {
                prime[q] = p;
            }
        }
    }
}
// Finding unique prime factors of n
set<int> getPrimeFactors(int num) {
    set<int> p_factors;
    // Store distinct prime factors
    while (num > 1) {
        p_factors.insert(prime[num]);
        num /= prime[num];
    }
    return p_factors;
}
int findMinimumSteps(int n, int m) {
    // To store distance from the start node
    queue<pair<int, int>> que;
    // BFS algorithm
    que.push({n, 0});
    while (!que.empty()) {
        // Get the first node from the queue
        int temp = que.front().first;
        int dist = que.front().second;
        que.pop();
            // When the temp is equal to m, we found steps
            if (temp == m) {
                return dist;
            }
            // When it is not possible to convert N to M
            else if (temp > m) {
                break;
            }
        // Finding prime factors
        set<int> p_factors = getPrimeFactors(temp);
        // Traverse prime factors
        for (auto p : p_factors) {
                // Insert pair to queue
                que.push({temp + p, dist + 1});
        }
    }
    // If we can't convert N to M
    return -1;
}
int main() {
    int N = 8, M = 12;
    getPrimeNumbers();
    int res = findMinimumSteps(N, M);
    if (res == -1) {
        cout << "It is not possible to convert " << N << " to " << M;
    } else {
        cout << "The minimum steps required to convert" << N << " to " << M << " is " << res;
    }
}

输出

The minimum steps required to convert8 to 12 is 2

时间复杂度 - O(M) 将N转换为M。

空间复杂度 -O(M) 将对存储到队列中。

我们使用单个问题学习了三个不同的子问题。第一个是使用筛法算法查找每个数字的最小质数。第二个是查找给定数字的所有质因数,第三个是通过将N的任何质因数加到自身来将N转换为M。

更新于: 2023年8月2日

60次浏览

开启你的 职业生涯

通过完成课程获得认证

开始学习
广告