📜  通过乘以A或除以B将N减为1的最小运算

📅  最后修改于: 2021-05-04 16:24:50             🧑  作者: 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,则考虑一个变量C的值是B / A。用第二个运算将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


输出:
3

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