Dado un número inicial x y dos operaciones que se dan a continuación:
- Multiplica el número por 2.
- Resta 1 del número.
La tarea es averiguar el número mínimo de operaciones requeridas para convertir el número x en y usando solo las dos operaciones anteriores. Podemos aplicar estas operaciones cualquier número de veces.
Restricciones:
1 <= x, y <= 1000
Ejemplo:
Input : x = 4, y = 7 Output : 2 We can transform x into y using following two operations. 1. 4*2 = 8 2. 8-1 = 7 Input : x = 2, y = 5 Output : 4 We can transform x into y using following four operations. 1. 2*2 = 4 2. 4-1 = 3 3. 3*2 = 6 4. 6-1 = 5 Answer = 4 Note that other sequences of two operations would take more operations.
La idea es usar BFS para esto. Ejecutamos un BFS y creamos Nodes multiplicando por 2 y restando por 1, por lo que podemos obtener todos los números posibles alcanzables desde el número inicial.
Puntos importantes :
- Cuando restamos 1 de un número y se convierte en <0, es decir, Negativo, entonces no hay razón para crear el siguiente Node a partir de él (según las restricciones de entrada, los números x e y son positivos).
- Además, si ya hemos creado un número, no hay motivo para volver a crearlo. es decir, mantenemos una array visitada.
Implementación:
C++
// C++ program to find minimum number of steps needed // to convert a number x into y with two operations // allowed : (1) multiplication with 2 (2) subtraction // with 1. #include <bits/stdc++.h> using namespace std; // A node of BFS traversal struct node { int val; int level; }; // Returns minimum number of operations // needed to convert x into y using BFS int minOperations(int x, int y) { // To keep track of visited numbers // in BFS. set<int> visit; // Create a queue and enqueue x into it. queue<node> q; node n = { x, 0 }; q.push(n); // Do BFS starting from x while (!q.empty()) { // Remove an item from queue node t = q.front(); q.pop(); // If the removed item is target // number y, return its level if (t.val == y) return t.level; // Mark dequeued number as visited visit.insert(t.val); // If we can reach y in one more step if (t.val * 2 == y || t.val - 1 == y) return t.level + 1; // Insert children of t if not visited // already if (visit.find(t.val * 2) == visit.end()) { n.val = t.val * 2; n.level = t.level + 1; q.push(n); } if (t.val - 1 >= 0 && visit.find(t.val - 1) == visit.end()) { n.val = t.val - 1; n.level = t.level + 1; q.push(n); } } } // Driver code int main() { int x = 4, y = 7; cout << minOperations(x, y); return 0; }
Java
// Java program to find minimum // number of steps needed to // convert a number x into y // with two operations allowed : // (1) multiplication with 2 // (2) subtraction with 1. import java.util.HashSet; import java.util.LinkedList; import java.util.Set; class GFG { int val; int steps; public GFG(int val, int steps) { this.val = val; this.steps = steps; } } public class GeeksForGeeks { private static int minOperations(int src, int target) { Set<GFG> visited = new HashSet<>(1000); LinkedList<GFG> queue = new LinkedList<GFG>(); GFG node = new GFG(src, 0); queue.offer(node); visited.add(node); while (!queue.isEmpty()) { GFG temp = queue.poll(); visited.add(temp); if (temp.val == target) { return temp.steps; } int mul = temp.val * 2; int sub = temp.val - 1; // given constraints if (mul > 0 && mul < 1000) { GFG nodeMul = new GFG(mul, temp.steps + 1); queue.offer(nodeMul); } if (sub > 0 && sub < 1000) { GFG nodeSub = new GFG(sub, temp.steps + 1); queue.offer(nodeSub); } } return -1; } // Driver code public static void main(String[] args) { // int x = 2, y = 5; int x = 4, y = 7; GFG src = new GFG(x, y); System.out.println(minOperations(x, y)); } } // This code is contributed by Rahul
Python3
# Python3 program to find minimum number of # steps needed to convert a number x into y # with two operations allowed : # (1) multiplication with 2 # (2) subtraction with 1. import queue # A node of BFS traversal class node: def __init__(self, val, level): self.val = val self.level = level # Returns minimum number of operations # needed to convert x into y using BFS def minOperations(x, y): # To keep track of visited numbers # in BFS. visit = set() # Create a queue and enqueue x into it. q = queue.Queue() n = node(x, 0) q.put(n) # Do BFS starting from x while (not q.empty()): # Remove an item from queue t = q.get() # If the removed item is target # number y, return its level if (t.val == y): return t.level # Mark dequeued number as visited visit.add(t.val) # If we can reach y in one more step if (t.val * 2 == y or t.val - 1 == y): return t.level+1 # Insert children of t if not visited # already if (t.val * 2 not in visit): n.val = t.val * 2 n.level = t.level + 1 q.put(n) if (t.val - 1 >= 0 and t.val - 1 not in visit): n.val = t.val - 1 n.level = t.level + 1 q.put(n) # Driver code if __name__ == '__main__': x = 4 y = 7 print(minOperations(x, y)) # This code is contributed by PranchalK
C#
// C# program to find minimum // number of steps needed to // convert a number x into y // with two operations allowed : // (1) multiplication with 2 // (2) subtraction with 1. using System; using System.Collections.Generic; public class GFG { public int val; public int steps; public GFG(int val, int steps) { this.val = val; this.steps = steps; } } public class GeeksForGeeks { private static int minOperations(int src, int target) { HashSet<GFG> visited = new HashSet<GFG>(1000); List<GFG> queue = new List<GFG>(); GFG node = new GFG(src, 0); queue.Add(node); visited.Add(node); while (queue.Count != 0) { GFG temp = queue[0]; queue.RemoveAt(0); visited.Add(temp); if (temp.val == target) { return temp.steps; } int mul = temp.val * 2; int sub = temp.val - 1; // given constraints if (mul > 0 && mul < 1000) { GFG nodeMul = new GFG(mul, temp.steps + 1); queue.Add(nodeMul); } if (sub > 0 && sub < 1000) { GFG nodeSub = new GFG(sub, temp.steps + 1); queue.Add(nodeSub); } } return -1; } // Driver code public static void Main(String[] args) { // int x = 2, y = 5; int x = 4, y = 7; GFG src = new GFG(x, y); Console.WriteLine(minOperations(x, y)); } } // This code is contributed by aashish1995
2
Este artículo es una contribución de Vipin Khushu . Si le gusta GeeksforGeeks y le gustaría contribuir, también puede escribir un artículo y enviarlo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.
Solución optimizada:
En el segundo enfoque, verificaremos el bit más pequeño del número y tomaremos una decisión de acuerdo con el valor de ese bit.
En lugar de convertir x en y, convertiremos y en x e invertiremos las operaciones, lo que requerirá el mismo número de operaciones que para convertir x en y.
Entonces, las operaciones inversas para y serán:
- Dividir número por 2
- Incrementar el número en 1
Implementación:
C++14
#include <iostream> using namespace std; int min_operations(int x, int y) { // If both are equal then return 0 if (x == y) return 0; // Check if conversion is possible or not if (x <= 0 && y > 0) return -1; // If x > y then we can just increase y by 1 // Therefore return the number of increments required if (x > y) return x - y; // If last bit is odd // then increment y so that we can make it even if (y & 1) return 1 + min_operations(x, y + 1); // If y is even then divide it by 2 to make it closer to // x else return 1 + min_operations(x, y / 2); } // Driver code signed main() { cout << min_operations(4, 7) << endl; return 0; }
C
#include <stdio.h> int min_operations(int x, int y) { // If both are equal then return 0 if (x == y) return 0; // Check if conversion is possible or not if (x <= 0 && y > 0) return -1; // If x > y then we can just increase y by 1 // Therefore return the number of increments required if (x > y) return x - y; // If last bit is odd // then increment y so that we can make it even if (y & 1) return 1 + min_operations(x, y + 1); // If y is even then divide it by 2 to make it closer to // x else return 1 + min_operations(x, y / 2); } // Driver code signed main() { printf("%d", min_operations(4, 7)); return 0; } // This code is contributed by Rohit Pradhan
Java
/*package whatever //do not write package name here */ import java.io.*; class GFG { static int minOperations(int x, int y) { // If both are equal then return 0 if (x == y) return 0; // Check if conversion is possible or not if (x <= 0 && y > 0) return -1; // If x > y then we can just increase y by 1 // Therefore return the number of increments // required if (x > y) return x - y; // If last bit is odd // then increment y so that we can make it even if (y % 2 != 0) return 1 + minOperations(x, y + 1); // If y is even then divide it by 2 to make it // closer to x else return 1 + minOperations(x, y / 2); } public static void main(String[] args) { System.out.println(minOperations(4, 7)); } } // This code is contributed by Shobhit Yadav
Python3
def min_operations(x, y): # If both are equal then return 0 if x == y: return 0 # Check if conversion is possible or not if x <= 0 and y > 0: return -1 # If x > y then we can just increase y by 1 # Therefore return the number of increments required if x > y: return a-b # If last bit is odd # then increment y so that we can make it even if y & 1 == 1: return 1+min_operations(x, y+1) # If y is even then divide it by 2 to make it closer to x else: return 1+min_operations(x, y//2) # Driver code print(min_operations(4, 7))
C#
using System; class GFG { static int min_operations(int x, int y) { // If both are equal then return 0 if (x == y) return 0; // Check if conversion is possible or not if (x <= 0 && y > 0) return -1; // If x > y then we can just increase y by 1 // Therefore return the number of increments // required if (x > y) return x - y; // If last bit is odd // then increment y so that we can make it even if (y % 2 == 1) return 1 + min_operations(x, y + 1); // If y is even then divide it by 2 to make it // closer to // x else return 1 + min_operations(x, y / 2); } // Driver code public static int Main() { Console.WriteLine(min_operations(4, 7)); return 0; } } // This code is contributed by Taranpreet
Javascript
<script> function min_operations(x,y) { // If both are equal then return 0 if (x == y) return 0; // Check if conversion is possible or not if (x <= 0 && y > 0) return -1; // If x > y then we can just increase y by 1 // Therefore return the number of increments required if (x > y) return x - y; // If last bit is odd // then increment y so that we can make it even if (y & 1) return 1 + min_operations(x, y + 1); // If y is even then divide it by 2 to make it closer to // x else return 1 + min_operations(x, y / 2); } // Driver code document.write(min_operations(4, 7)); // This code is contributed by Taranpreet </script>
2
La solución optimizada es aportada por BurningTiles. Si le gusta GeeksforGeeks y le gustaría contribuir, también puede escribir un artículo y enviarlo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.
Publicación traducida automáticamente
Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA