📌  相关文章
📜  通过重复除以小于M的任何素数来使两个值相等所需的步骤最小化

📅  最后修改于: 2021-04-17 19:23:02             🧑  作者: Mango

给定三个正整数MXY ,任务是找到使XY相等所需的最小操作数,以便在每个操作中将XY除以小于M的素数之一。如果不可能使XY相等,则打印“ -1”

例子:

方法:以解决给定问题的想法是基于以下观察,在其中XY均为相等的值是XYGCD。请按照以下步骤解决问题:

  • 使用Eratosthenes筛子预先计算所有数字的质数,直到10 6并将其存储在数组中。
  • 计算数字XY的GCD并将其值存储在变量中,例如GCD
  • 现在,计算X / GCDY / GCD中素数的数量。如果任何素数的值都大于M ,则不可能使XY相等。因此,打印“ -1”
  • 否则,作为结果打印X / GCDY / GCD中素数的总和。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Stores the prime factor of numbers
int primes[1000006];
 
// Function to find GCD of a and b
int gcd(int a, int b)
{
     
    // Base Case
    if (b == 0)
        return a;
 
    // Otherwise, calculate GCD
    else
        return gcd(b, a % b);
}
 
// Function to precompute the
// prime numbers till 1000000
void preprocess()
{
     
    // Initialize all the positions
    // with their respective values
    for(int i = 1; i <= 1000000; i++)
        primes[i] = i;
 
    // Iterate over the range [2, sqrt(10^6)]
    for(int i = 2; i * i <= 1000000; i++)
    {
         
        // If i is prime number
        if (primes[i] == i)
        {
             
            // Mark it as the factor
            for(int j = 2 * i; j <= 1000000; j += i)
            {
                if (primes[j] == j)
                    primes[j] = i;
            }
        }
    }
}
 
// Utility function to count the number
// of steps to make X and Y equal
int Steps(int x, int m)
{
     
    // Intialise steps
    int steps = 0;
 
    bool flag = false;
 
    // Iterate x is at most 1
    while (x > 1)
    {
        if (primes[x] > m)
        {
            flag = true;
            break;
        }
 
        // Divide with the
        // smallest prime factor
        x /= primes[x];
 
        steps++;
    }
 
    // If X and Y can't be
    // made equal
    if (flag)
        return -1;
 
    // Return steps
    return steps;
}
 
// Function to find the minimum number of
// steps required to make X and Y equal
int minimumSteps(int x, int y, int m)
{
     
    // Generate all the prime factors
    preprocess();
 
    // Calculate GCD of x and y
    int g = gcd(x, y);
 
    // Divide the numbers by their gcd
    x = x / g;
    y = y / g;
 
    int x_steps = Steps(x, m);
    int y_steps = Steps(y, m);
 
    // If not possible, then return -1;
    if (x_steps == -1 || y_steps == -1)
        return -1;
 
    // Return the resultant number of steps
    return x_steps + y_steps;
}
 
// Driver Code
int main()
{
    int X = 160;
    int Y = 180;
    int M = 10;
 
    cout << (minimumSteps(X, Y, M));
}
 
// This code is contributed by chitranayal


Java
// Java program for the above approach
import java.util.*;
 
public class GFG {
 
    // Stores the prime factor of numbers
    static int primes[] = new int[1000006];
 
    // Function to find GCD of a and b
    static int gcd(int a, int b)
    {
        // Base Case
        if (b == 0)
            return a;
 
        // Otherwise, calculate GCD
        else
            return gcd(b, a % b);
    }
 
    // Function to precompute the
    // prime numbers till 1000000
    static void preprocess()
    {
        // Initialize all the positions
        // with their respective values
        for (int i = 1; i <= 1000000; i++)
            primes[i] = i;
 
        // Iterate over the range [2, sqrt(10^6)]
        for (int i = 2; i * i <= 1000000; i++) {
 
            // If i is prime number
            if (primes[i] == i) {
 
                // Mark it as the factor
                for (int j = 2 * i;
                     j <= 1000000; j += i) {
 
                    if (primes[j] == j)
                        primes[j] = i;
                }
            }
        }
    }
 
    // Utility function to count the number
    // of steps to make X and Y equal
    static int Steps(int x, int m)
    {
        // Intialise steps
        int steps = 0;
 
        boolean flag = false;
 
        // Iterate x is at most 1
        while (x > 1) {
            if (primes[x] > m) {
                flag = true;
                break;
            }
 
            // Divide with the
            // smallest prime factor
            x /= primes[x];
 
            steps++;
        }
 
        // If X and Y can't be
        // made equal
        if (flag)
            return -1;
 
        // Return steps
        return steps;
    }
 
    // Function to find the minimum number of
    // steps required to make X and Y equal
    static int minimumSteps(int x, int y, int m)
    {
        // Generate all the prime factors
        preprocess();
 
        // Calculate GCD of x and y
        int g = gcd(x, y);
 
        // Divide the numbers by their gcd
        x = x / g;
        y = y / g;
 
        int x_steps = Steps(x, m);
        int y_steps = Steps(y, m);
 
        // If not possible, then return -1;
        if (x_steps == -1 || y_steps == -1)
            return -1;
 
        // Return the resultant number of steps
        return x_steps + y_steps;
    }
 
    // Driver Code
    public static void main(String args[])
    {
        int X = 160;
        int Y = 180;
        int M = 10;
 
        System.out.println(
            minimumSteps(X, Y, M));
    }
}


Python3
# Python program for the above approach
 
# Stores the prime factor of numbers
primes = [0] * (1000006)
 
# Function to find GCD of a and b
def gcd(a, b) :
     
    # Base Case
    if (b == 0) :
        return a
 
    # Otherwise, calculate GCD
    else :
        return gcd(b, a % b)
 
 
# Function to precompute the
# prime numbers till 1000000
def preprocess() :
     
    # Initialize all the positions
    # with their respective values
    for i in range(1, 1000001):
        primes[i] = i
 
    # Iterate over the range [2, sqrt(10^6)]
    i = 2
    while(i * i <= 1000000)  :
         
        # If i is prime number
        if (primes[i] == i) :
             
            # Mark it as the factor
            for j in range(2 * i, 1000001, i):
                if (primes[j] == j) :
                    primes[j] = i     
        i += 1
 
# Utility function to count the number
# of steps to make X and Y equal
def Steps(x, m) :
     
    # Intialise steps
    steps = 0
 
    flag = False
 
    # Iterate x is at most 1
    while (x > 1) :
         
        if (primes[x] > m) :
            flag = True
            break
         
 
        # Divide with the
        # smallest prime factor
        x //= primes[x]
 
        steps += 1
     
 
    # If X and Y can't be
    # made equal
    if (flag != 0) :
        return -1
 
    # Return steps
    return steps
 
 
# Function to find the minimum number of
# steps required to make X and Y equal
def minimumSteps(x, y, m) :
     
    # Generate all the prime factors
    preprocess()
 
    # Calculate GCD of x and y
    g = gcd(x, y)
 
    # Divide the numbers by their gcd
    x = x // g
    y = y // g
 
    x_steps = Steps(x, m)
    y_steps = Steps(y, m)
 
    # If not possible, then return -1
    if (x_steps == -1 or y_steps == -1) :
        return -1
 
    # Return the resultant number of steps
    return x_steps + y_steps
 
 
# Driver Code
X = 160
Y = 180
M = 10
 
print(minimumSteps(X, Y, M))
 
# This code is contributed by souravghosh0416.


C#
// C# program for the above approach
using System;
 
class GFG{
 
// Stores the prime factor of numbers
static int[] primes = new int[1000006];
 
// Function to find GCD of a and b
static int gcd(int a, int b)
{
     
    // Base Case
    if (b == 0)
        return a;
     
    // Otherwise, calculate GCD
    else
        return gcd(b, a % b);
}
 
// Function to precompute the
// prime numbers till 1000000
static void preprocess()
{
     
    // Initialize all the positions
    // with their respective values
    for(int i = 1; i <= 1000000; i++)
        primes[i] = i;
     
    // Iterate over the range [2, sqrt(10^6)]
    for(int i = 2; i * i <= 1000000; i++)
    {
         
        // If i is prime number
        if (primes[i] == i)
        {
             
            // Mark it as the factor
            for(int j = 2 * i;
                    j <= 1000000; j += i)
            {
                if (primes[j] == j)
                    primes[j] = i;
            }
        }
    }
}
 
// Utility function to count the number
// of steps to make X and Y equal
static int Steps(int x, int m)
{
     
    // Intialise steps
    int steps = 0;
     
    bool flag = false;
     
    // Iterate x is at most 1
    while (x > 1)
    {
        if (primes[x] > m)
        {
            flag = true;
            break;
        }
         
        // Divide with the
        // smallest prime factor
        x /= primes[x];
         
        steps++;
    }
     
    // If X and Y can't be
    // made equal
    if (flag)
        return -1;
     
    // Return steps
    return steps;
}
 
// Function to find the minimum number of
// steps required to make X and Y equal
static int minimumSteps(int x, int y, int m)
{
     
    // Generate all the prime factors
    preprocess();
     
    // Calculate GCD of x and y
    int g = gcd(x, y);
     
    // Divide the numbers by their gcd
    x = x / g;
    y = y / g;
     
    int x_steps = Steps(x, m);
    int y_steps = Steps(y, m);
     
    // If not possible, then return -1;
    if (x_steps == -1 || y_steps == -1)
        return -1;
     
    // Return the resultant number of steps
    return x_steps + y_steps;
}
 
// Driver code
static void Main()
{
    int X = 160;
    int Y = 180;
    int M = 10;
     
    Console.Write(minimumSteps(X, Y, M));
}
}
 
// This code is contributed by sanjoy_62


Javascript


输出:
5

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