📌  相关文章
📜  通过乘以 A 或除以 B 将 N 减少到 1 的最小操作

📅  最后修改于: 2021-10-27 03:21:35             🧑  作者: Mango

给定一个数字N和两个整数AB ,任务是检查是否可以通过以下两个操作将数字转换为1

  • 乘以A
  • 除以 B

如果可以将N减少到1,则打印实现它所需的最少操作次数,否则打印“-1”

例子:

方法:该问题可以使用贪心方法解决。这个想法是检查 B 是否可以被 A 整除,并在此基础上我们有以下观察结果:

  • 如果B%A != 0 ,那么只有在N完全可以被B整除的情况下才可能将N转换为1并且需要N/B 步骤来这样做。而如果N = 1那么它将需要 0 个步骤,否则它是不可能的并打印“-1”
  • 如果B%A == 0 ,则考虑值为B/A的变量C N 除以 B ,使用第二个操作直到不能再除,我们称除法数为x。
  • 将剩余的N再除以C,直到不能再除为止,我们称此操作中的除法次数为y。
  • 如果经过上述运算后 N 不等于 1,则无法使用上述运算将N转换为1 ,答案将为“-1” ,但如果等于 1,则可以使用公式total_steps = x + (2 * y)计算所需的总最小步数。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to check if it is possible
// to convert a number N to 1 by a minimum
// use of the two operations
int findIfPossible(int n, int a, int b)
{
    // For the Case b % a != 0
    if (b % a != 0) {
 
        // Check if n equal to 1
        if (n == 1)
            return 0;
 
        // Check if n is not
        // divisible by b
        else if (n % b != 0)
            return -1;
        else
            return (int)n / b;
    }
 
    // For the Case b % a == 0
 
    // Initialize a variable 'c'
    int c = b / a;
    int x = 0, y = 0;
 
    // Loop until n is divisible by b
    while (n % b == 0) {
        n = n / b;
 
        // Count number of divisions
        x++;
    }
 
    // Loop until n is divisible by c
    while (n % c == 0) {
        n = n / c;
 
        // Count number of operations
        y++;
    }
 
    // Check if n is reduced to 1
    if (n == 1) {
 
        // Count steps
        int total_steps = x + (2 * y);
 
        // Return the total number of steps
        return total_steps;
    }
    else
        return -1;
}
 
// Driver Code
int main()
{
    // Given n, a and b
    int n = 48;
    int a = 3, b = 12;
 
    // Function Call
    cout << findIfPossible(n, a, b);
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
     
// Function to check if it is possible
// to convert a number N to 1 by a minimum
// use of the two operations
static int findIfPossible(int n, int a, int b)
{
     
    // For the Case b % a != 0
    if (b % a != 0)
    {
 
        // Check if n equal to 1
        if (n == 1)
            return 0;
 
        // Check if n is not
        // divisible by b
        else if (n % b != 0)
            return -1;
        else
            return (int)n / b;
    }
 
    // For the Case b % a == 0
 
    // Initialize a variable 'c'
    int c = b / a;
    int x = 0, y = 0;
 
    // Loop until n is divisible by b
    while (n % b == 0)
    {
        n = n / b;
 
        // Count number of divisions
        x++;
    }
 
    // Loop until n is divisible by c
    while (n % c == 0)
    {
        n = n / c;
 
        // Count number of operations
        y++;
    }
 
    // Check if n is reduced to 1
    if (n == 1)
    {
 
        // Count steps
        int total_steps = x + (2 * y);
 
        // Return the total number of steps
        return total_steps;
    }
    else
        return -1;
}
 
// Driver Code
public static void main(String s[])
{
     
    // Given n, a and b
    int n = 48;
    int a = 3, b = 12;
     
    // Function Call
    System.out.println(findIfPossible(n, a, b));
}
}
 
// This code is contributed by rutvik_56


Python3
# Python3 program for the above approach
 
# Function to check if it is possible
# to convert a number N to 1 by a minimum
# use of the two operations
def FindIfPossible(n, a, b):
     
    # For the Case b % a != 0
    if (b % a) != 0:
         
    # Check if n equal to 1
        if n == 1:
            return 0
         
        # Check if n is not
        # divisible by b
        elif (n % b) != 0:
            return -1
        else:
            return int(n / b)
     
    # For the Case b % a == 0
    # Initialize a variable 'c'
    c = b / a
    x = 0
    y = 0
     
    # Loop until n is divisible by b
    while (n % b == 0):
        n /= b
         
    # Count number of divisions
        x += 1
         
    # Loop until n is divisible by c
    while (n % c == 0):
        n /= c
         
        # Count number of operations
        y += 1
     
    # Check if n is reduced to 1
    if n == 1:
         
        # Count steps
        total_steps = x + 2 * y
         
        # Return the total number of steps
        return total_steps
    else:
        return -1
         
# Driver code
 
# Given n, a and b
n = 48
a = 3
b = 12
 
print(FindIfPossible(n, a, b))
 
# This code is contributed by virusbuddah_


C#
// C# program for the above approach
using System;
 
class GFG{
     
// Function to check if it is possible
// to convert a number N to 1 by a minimum
// use of the two operations
static int findIfPossible(int n, int a, int b)
{
     
    // For the Case b % a != 0
    if (b % a != 0)
    {
 
        // Check if n equal to 1
        if (n == 1)
            return 0;
 
        // Check if n is not
        // divisible by b
        else if (n % b != 0)
            return -1;
        else
            return (int)n / b;
    }
 
    // For the Case b % a == 0
 
    // Initialize a variable 'c'
    int c = b / a;
    int x = 0, y = 0;
 
    // Loop until n is divisible by b
    while (n % b == 0)
    {
        n = n / b;
 
        // Count number of divisions
        x++;
    }
 
    // Loop until n is divisible by c
    while (n % c == 0)
    {
        n = n / c;
 
        // Count number of operations
        y++;
    }
 
    // Check if n is reduced to 1
    if (n == 1)
    {
 
        // Count steps
        int total_steps = x + (2 * y);
 
        // Return the total number of steps
        return total_steps;
    }
    else
        return -1;
}
 
// Driver Code
public static void Main()
{
     
    // Given n, a and b
    int n = 48;
    int a = 3, b = 12;
     
    // Function call
    Console.WriteLine(findIfPossible(n, a, b));
}
}
 
// This code is contributed by Stream_Cipher


Javascript


输出:
3

时间复杂度: O(log (B/A))
辅助空间: O(1)