Minimum steps to reach end from start by performing multiplication and mod operations with array elements

Given start, end and an array of N numbers. At each step, start is multiplied with any number in the array and then mod operation with 100000 is done to get the new start. The task is to find the minimum steps in which end can be achieved starting from start.Â
Examples:Â
Â
Input: start = 3 end = 30 a[] = {2, 5, 7}Â
Output: 2Â
Step 1: 3*2 = 6 % 100000 = 6Â
Step 2: 6*5 = 30 % 100000 = 30Â
Input: start = 7 end = 66175 a[] = {3, 4, 65}Â
Output: 4Â
Step 1: 7*3 = 21 % 100000 = 21Â
Step 2: 21*3 = 6 % 100000 = 63Â
Step 3: 63*65 = 4095 % 100000 = 4095Â
Step 4: 4095*65 = 266175 % 100000 = 66175Â
Â
Approach: Since in the above problem the modulus given is 100000, therefore the maximum number of states will be 105. All the states can be checked using simple BFS. Initialize an ans[] array with -1 which marks that the state has not been visited. ans[i] stores the number of steps taken to reach i from start. Initially push the start to the queue, then apply BFS. Pop the top element and check if it is equal to the end, if it is then print the ans[end]. If the element is not equal to the topmost element, then multiply top element with every element in the array and perform a mod operation. If the multiplied element state has not been visited previously, then push it into the queue. Initialize ans[pushed_element] by ans[top_element] + 1. Once all the states are visited, and the state cannot be reached by performing every possible multiplication, then print -1.Â
Below is the implementation of the above approach:Â
Â
C++
// C++ program to find the minimum steps// to reach end from start by performing// multiplications and mod operations with array elements#include <bits/stdc++.h>using namespace std;Â
// Function that returns the minimum operationsint minimumMulitplications(int start, int end, int a[], int n){    // array which stores the minimum steps    // to reach i from start    int ans[100001];Â
    // -1 indicated the state has not been visited    memset(ans, -1, sizeof(ans));    int mod = 100000;Â
    // queue to store all possible states    queue<int> q;Â
    // initially push the start    q.push(start % mod);Â
    // to reach start we require 0 steps    ans[start] = 0;Â
    // till all states are visited    while (!q.empty()) {Â
        // get the topmost element in the queue        int top = q.front();Â
        // pop the topmost element        q.pop();Â
        // if the topmost element is end        if (top == end)            return ans[end];Â
        // perform multiplication with all array elements        for (int i = 0; i < n; i++) {            int pushed = top * a[i];            pushed = pushed % mod;Â
            // if not visited, then push it to queue            if (ans[pushed] == -1) {                ans[pushed] = ans[top] + 1;                q.push(pushed);            }        }    }    return -1;}Â
// Driver Codeint main(){Â Â Â Â int start = 7, end = 66175;Â Â Â Â int a[] = { 3, 4, 65 };Â Â Â Â int n = sizeof(a) / sizeof(a[0]);Â
    // Calling function    cout << minimumMulitplications(start, end, a, n);    return 0;} |
Java
// Java program to find the minimum steps // to reach end from start by performing // multiplications and mod operations with array elements Â
import java.util.Arrays;import java.util.LinkedList;import java.util.Queue;Â
class GFG {Â
// Function that returns the minimum operations     static int minimumMulitplications(int start, int end, int a[], int n) {        // array which stores the minimum steps         // to reach i from start         int ans[] = new int[100001];Â
        // -1 indicated the state has not been visited         Arrays.fill(ans, -1);        int mod = 100000;Â
        // queue to store all possible states         Queue<Integer> q = new LinkedList<>();Â
        // initially push the start         q.add(start % mod);Â
        // to reach start we require 0 steps         ans[start] = 0;Â
        // till all states are visited         while (!q.isEmpty()) {Â
            // get the topmost element in the queue             int top = q.peek();Â
            // pop the topmost element             q.remove();Â
            // if the topmost element is end             if (top == end) {                return ans[end];            }Â
            // perform multiplication with all array elements             for (int i = 0; i < n; i++) {                int pushed = top * a[i];                pushed = pushed % mod;Â
                // if not visited, then push it to queue                 if (ans[pushed] == -1) {                    ans[pushed] = ans[top] + 1;                    q.add(pushed);                }            }        }        return -1;    }Â
// Driver Code     public static void main(String args[]) {        int start = 7, end = 66175;        int a[] = {3, 4, 65};        int n = a.length;Â
        // Calling function         System.out.println(minimumMulitplications(start, end, a, n));Â
    }}Â
// This code is contributed by PrinciRaj19992 |
Python3
# Python3 program to find the minimum steps # to reach end from start by performing # multiplications and mod operations with # array elements from collections import dequeÂ
# Function that returns the minimum operationsdef minimumMulitplications(start, end, a, n):         # array which stores the minimum     # steps to reach i from start    ans = [-1 for i in range(100001)]Â
    # -1 indicated the state has     # not been visited    mod = 100000Â
    q = deque()         # queue to store all possible states    # initially push the start    q.append(start % mod)Â
    # to reach start we require 0 steps    ans[start] = 0Â
    # till all states are visited    while (len(q) > 0):Â
        # get the topmost element in the         # queue, pop the topmost element        top = q.popleft()Â
        # if the topmost element is end        if (top == end):            return ans[end]Â
        # perform multiplication with         # all array elements        for i in range(n):            pushed = top * a[i]            pushed = pushed % modÂ
            # if not visited, then push it to queue            if (ans[pushed] == -1):                ans[pushed] = ans[top] + 1                q.append(pushed)                 return -1Â
# Driver Codestart = 7end = 66175a = [3, 4, 65]n = len(a)Â
# Calling functionprint(minimumMulitplications(start, end, a, n))Â
# This code is contributed by mohit kumar |
C#
// C# program to find the minimum steps // to reach end from start by performing // multiplications and mod operations with array elements using System;using System.Collections.Generic; Â Â Â Â Â class GFG{Â
    // Function that returns the minimum operations     static int minimumMulitplications(int start, int end,                                             int []a, int n)     {        // array which stores the minimum steps         // to reach i from start         int []ans = new int[100001];Â
        // -1 indicated the state has not been visited         for(int i = 0; i < ans.Length; i++)            ans[i] = -1;        int mod = 100000;Â
        // queue to store all possible states         Queue<int> q = new Queue<int>();Â
        // initially push the start         q.Enqueue(start % mod);Â
        // to reach start we require 0 steps         ans[start] = 0;Â
        // till all states are visited         while (q.Count != 0)         {Â
            // get the topmost element in the queue             int top = q.Peek();Â
            // pop the topmost element             q.Dequeue();Â
            // if the topmost element is end             if (top == end)             {                return ans[end];            }Â
            // perform multiplication with all array elements             for (int i = 0; i < n; i++)            {                int pushed = top * a[i];                pushed = pushed % mod;Â
                // if not visited, then push it to queue                 if (ans[pushed] == -1)                 {                    ans[pushed] = ans[top] + 1;                    q.Enqueue(pushed);                }            }        }        return -1;    }Â
    // Driver Code     public static void Main(String []args)     {        int start = 7, end = 66175;        int []a = {3, 4, 65};        int n = a.Length;Â
        // Calling function         Console.WriteLine(minimumMulitplications(start, end, a, n));Â
    }}Â
/* This code contributed by PrinciRaj1992 */ |
Javascript
<script>// Javascript program to find the minimum steps // to reach end from start by performing // multiplications and mod operations with array elements          // Function that returns the minimum operations     function minimumMulitplications(start,end,a,n)    {        // array which stores the minimum steps         // to reach i from start         let ans = new Array(100001);           // -1 indicated the state has not been visited         for(let i=0;i<ans.length;i++)        {            ans[i]=-1;        }                 let mod = 100000;           // queue to store all possible states         let q = [];           // initially push the start         q.push(start % mod);           // to reach start we require 0 steps         ans[start] = 0;           // till all states are visited         while (q.length!=0) {               // get the topmost element in the queue             let top = q[0];               // pop the topmost element             q.shift();               // if the topmost element is end             if (top == end) {                return ans[end];            }               // perform multiplication with all array elements             for (let i = 0; i < n; i++) {                let pushed = top * a[i];                pushed = pushed % mod;                   // if not visited, then push it to queue                 if (ans[pushed] == -1) {                    ans[pushed] = ans[top] + 1;                    q.push(pushed);                }            }        }        return -1;    }         // Driver Code     let start = 7, end = 66175;    let a=[3, 4, 65];    let n = a.length;         // Calling function     document.write(minimumMulitplications(start, end, a, n));          // This code is contributed by unknown2108</script> |
4
Â
Time Complexity: O(n)
Auxiliary Space: O(n)
Another Approach: using Bidirectional Search
- Initialize two queues, one for start and one for end. Push start and end to their respective queues.
- Initialize two ans[] arrays for both start and end. ans[i] stores the number of steps taken to reach i from start or end, depending on which queue it belongs to.
- Initialize a visited[] array which marks if the state has been visited or not. visited[i] stores true if the state i has been visited.
- Initialize a commonNode variable to -1, indicating no common node has been found yet.
- While both queues are not empty, do the following:
a. Choose the queue with the smaller size, and pop the front element. Let this element be x.
b. If x is already visited, continue to the next element in the queue.
c. For each element y in the array a[], calculate yx%mod. If this state is already visited by the other queue, then we have found a common node. Update commonNode to yx%mod and return ans[start] + ans[end].
d. If this state has not been visited before, add it to the queue, mark it as visited, and update ans[] for this state. - If no common node is found after visiting all possible states, return -1.
- Done
C++
// C++ program to find the minimum steps// to reach end from start by performing// multiplications and mod operations with array elements#include <bits/stdc++.h>using namespace std;Â
// Function that returns the minimum operationsint minimumMultiplications(int start, int end, int a[],                           int n){    // array which stores the minimum steps    // to reach i from start or end    int ans_start[100001], ans_end[100001];    // visited array to keep track of visited states    bool visited_start[100001], visited_end[100001];Â
    // -1 indicated the state has not been visited    memset(ans_start, -1, sizeof(ans_start));    memset(ans_end, -1, sizeof(ans_end));    memset(visited_start, false, sizeof(visited_start));    memset(visited_end, false, sizeof(visited_end));Â
    int mod = 100000;Â
    // queues to store all possible states    queue<int> q_start, q_end;Â
    // initially push start and end    q_start.push(start % mod);    q_end.push(end % mod);Â
    // to reach start or end we require 0 steps    ans_start[start] = 0;    ans_end[end] = 0;Â
    // mark start and end as visited    visited_start[start] = true;    visited_end[end] = true;Â
    // variable to store common node    int commonNode = -1;Â
    // till all states are visited or common node is found    while (!q_start.empty() && !q_end.empty()) {Â
        // choose the queue with smaller size        if (q_start.size() < q_end.size()) {            int top = q_start.front();            q_start.pop();Â
            // if the topmost element is end            if (visited_end[top]) {                commonNode = top;                break;            }Â
            // perform multiplication with all array            // elements            for (int i = 0; i < n; i++) {                int pushed = top * a[i];                pushed = pushed % mod;Â
                // if not visited, then push it to queue                if (!visited_start[pushed]) {                    ans_start[pushed] = ans_start[top] + 1;                    q_start.push(pushed);                    visited_start[pushed] = true;                }            }        }        else {            int top = q_end.front();            q_end.pop();Â
            // if the topmost element is start            if (visited_start[top]) {                commonNode = top;                break;            }Â
            // perform multiplication with all array            // elements            for (int i = 0; i < n; i++) {                int pushed = top * a[i];                pushed = pushed % mod;Â
                // if not visited, then push it to queue                if (!visited_end[pushed]) {                    ans_end[pushed] = ans_end[top] + 1;                    q_end.push(pushed);                    visited_end[pushed] = true;                }            }        }    }Â
    if (commonNode == -1)        return -1;Â
    // return the sum of minimum steps from start and end to    // common node    return ans_start[commonNode] + ans_end[commonNode];}Â
// Driver Codeint main(){    int start = 7, end = 66175;    int a[] = { 3, 4, 65 };    int n = sizeof(a) / sizeof(a[0]);    // Calling function    cout << minimumMultiplications(start, end, a, n);    return 0;} |
Java
import java.util.*;Â
public class Main {    // Function that returns the minimum operations    static int minimumMultiplications(int start, int end, int a[], int n) {        // array which stores the minimum steps        // to reach i from start or end        int ans_start[] = new int[100001];        int ans_end[] = new int[100001];        Arrays.fill(ans_start, -1);        Arrays.fill(ans_end, -1);Â
        // visited array to keep track of visited states        boolean visited_start[] = new boolean[100001];        boolean visited_end[] = new boolean[100001];Â
        int mod = 100000;Â
        // queues to store all possible states        Queue<Integer> q_start = new LinkedList<>();        Queue<Integer> q_end = new LinkedList<>();Â
        // initially push start and end        q_start.add(start % mod);        q_end.add(end % mod);Â
        // to reach start or end we require 0 steps        ans_start[start] = 0;        ans_end[end] = 0;Â
        // mark start and end as visited        visited_start[start] = true;        visited_end[end] = true;Â
        // variable to store common node        int commonNode = -1;Â
        // till all states are visited or common node is found        while (!q_start.isEmpty() && !q_end.isEmpty()) {            // choose the queue with smaller size            if (q_start.size() < q_end.size()) {                int top = q_start.poll();Â
                // if the topmost element is end                if (visited_end[top]) {                    commonNode = top;                    break;                }Â
                // perform multiplication with all array elements                for (int i = 0; i < n; i++) {                    int pushed = top * a[i];                    pushed = pushed % mod;Â
                    // if not visited, then push it to queue                    if (!visited_start[pushed]) {                        ans_start[pushed] = ans_start[top] + 1;                        q_start.add(pushed);                        visited_start[pushed] = true;                    }                }            } else {                int top = q_end.poll();Â
                // if the topmost element is start                if (visited_start[top]) {                    commonNode = top;                    break;                }Â
                // perform multiplication with all array elements                for (int i = 0; i < n; i++) {                    int pushed = top * a[i];                    pushed = pushed % mod;Â
                    // if not visited, then push it to queue                    if (!visited_end[pushed]) {                        ans_end[pushed] = ans_end[top] + 1;                        q_end.add(pushed);                        visited_end[pushed] = true;                    }                }            }        }Â
        if (commonNode == -1)            return -1;Â
        // return the sum of minimum steps from start and end to common node        return ans_start[commonNode] + ans_end[commonNode];    }Â
    // Driver Code    public static void main(String[] args) {        int start = 7, end = 66175;        int a[] = { 3, 4, 65 };        int n = a.length;        // Calling function        System.out.println(minimumMultiplications(start, end, a, n));    }} |
Python3
from queue import QueueÂ
# Function that returns the minimum operationsdef minimumMultiplications(start, end, a, n):    # array which stores the minimum steps    # to reach i from start or end    ans_start, ans_end = [-1] * 100001, [-1] * 100001    # visited array to keep track of visited states    visited_start, visited_end = [False] * 100001, [False] * 100001Â
    mod = 100000Â
    # queues to store all possible states    q_start, q_end = Queue(), Queue()Â
    # initially push start and end    q_start.put(start % mod)    q_end.put(end % mod)Â
    # to reach start or end we require 0 steps    ans_start[start] = 0    ans_end[end] = 0Â
    # mark start and end as visited    visited_start[start] = True    visited_end[end] = TrueÂ
    # variable to store common node    commonNode = -1Â
    # till all states are visited or common node is found    while not q_start.empty() and not q_end.empty():Â
        # choose the queue with smaller size        if q_start.qsize() < q_end.qsize():            top = q_start.get()Â
            # if the topmost element is end            if visited_end[top]:                commonNode = top                breakÂ
            # perform multiplication with all array elements            for i in range(n):                pushed = top * a[i]                pushed = pushed % modÂ
                # if not visited, then push it to queue                if not visited_start[pushed]:                    ans_start[pushed] = ans_start[top] + 1                    q_start.put(pushed)                    visited_start[pushed] = True        else:            top = q_end.get()Â
            # if the topmost element is start            if visited_start[top]:                commonNode = top                breakÂ
            # perform multiplication with all array elements            for i in range(n):                pushed = top * a[i]                pushed = pushed % modÂ
                # if not visited, then push it to queue                if not visited_end[pushed]:                    ans_end[pushed] = ans_end[top] + 1                    q_end.put(pushed)                    visited_end[pushed] = TrueÂ
    if commonNode == -1:        return -1Â
    # return the sum of minimum steps from start and end to common node    return ans_start[commonNode] + ans_end[commonNode]Â
# Driver Codeif __name__ == "__main__":    start, end = 7, 66175    a = [3, 4, 65]    n = len(a)    # Calling function    print(minimumMultiplications(start, end, a, n)) |
C#
// C# program to find the minimum steps// to reach end from start by performing// multiplications and mod operations with array elementsusing System;using System.Collections.Generic;Â
class Gfg{Â
  // Function that returns the minimum operations  static int minimumMultiplications(int start, int end, int[] a, int n)  {Â
    // array which stores the minimum steps    // to reach i from start or end    int[] ans_start = new int[100001];    int[] ans_end = new int[100001];    // visited array to keep track of visited states    bool[] visited_start = new bool[100001];    bool[] visited_end = new bool[100001];Â
    // -1 indicated the state has not been visited    Array.Fill(ans_start, -1);    Array.Fill(ans_end, -1);    Array.Fill(visited_start, false);    Array.Fill(visited_end, false);Â
    int mod = 100000;Â
    // queues to store all possible states    Queue<int> q_start = new Queue<int>();    Queue<int> q_end = new Queue<int>();Â
    // initially push start and end    q_start.Enqueue(start % mod);    q_end.Enqueue(end % mod);Â
    // to reach start or end we require 0 steps    ans_start[start] = 0;    ans_end[end] = 0;Â
    // mark start and end as visited    visited_start[start] = true;    visited_end[end] = true;Â
    // variable to store common node    int commonNode = -1;Â
    // till all states are visited or common node is found    while (q_start.Count > 0 && q_end.Count > 0)    {      // choose the queue with smaller size      if (q_start.Count < q_end.Count)      {        int top = q_start.Dequeue();Â
        // if the topmost element is end        if (visited_end[top])        {          commonNode = top;          break;        }Â
        // perform multiplication with all array        // elements        for (int i = 0; i < n; i++)        {          int pushed = top * a[i];          pushed = pushed % mod;Â
          // if not visited, then push it to queue          if (!visited_start[pushed])          {            ans_start[pushed] = ans_start[top] + 1;            q_start.Enqueue(pushed);            visited_start[pushed] = true;          }        }      }      else      {        int top = q_end.Dequeue();Â
        // if the topmost element is start        if (visited_start[top])        {          commonNode = top;          break;        }Â
        // perform multiplication with all array        // elements        for (int i = 0; i < n; i++)        {          int pushed = top * a[i];          pushed = pushed % mod;Â
          // if not visited, then push it to queue          if (!visited_end[pushed])          {            ans_end[pushed] = ans_end[top] + 1;            q_end.Enqueue(pushed);            visited_end[pushed] = true;          }        }      }    }Â
    if (commonNode == -1)      return -1;Â
    // return the sum of minimum steps from start and end to    // common node    return ans_start[commonNode] + ans_end[commonNode];  }Â
  // Driver Code  static void Main(string[] args)  {    int start = 7, end = 66175;    int[] a = { 3, 4, 65 };    int n = a.Length;Â
    // Calling function    Console.WriteLine(minimumMultiplications(start, end, a, n));  }} |
Javascript
// Javascript program to find the minimum steps// to reach end from start by performing// multiplications and mod operations with array elementsÂ
// Function that returns the minimum operationsfunction minimumMultiplications(start, end, a, n) {  // array which stores the minimum steps to reach i from start  const ans_start = new Array(100001).fill(-1);   // array which stores the minimum steps to reach i from end  const ans_end = new Array(100001).fill(-1);   // visited array to keep track of visited states from start  const visited_start = new Array(100001).fill(false);   // visited array to keep track of visited states from end  const visited_end = new Array(100001).fill(false); Â
  const mod = 100000;Â
  const q_start = []; // queue to store states from start  const q_end = []; // queue to store states from endÂ
  // initially push start and end  q_start.push(start % mod);  q_end.push(end % mod);Â
  // to reach start or end we require 0 steps  ans_start[start] = 0;  ans_end[end] = 0;Â
  // mark start and end as visited  visited_start[start] = true;  visited_end[end] = true;Â
  let commonNode = -1; // variable to store common nodeÂ
  // till all states are visited or common node is found  while (q_start.length > 0 && q_end.length > 0) {    // choose the queue with smaller size    if (q_start.length < q_end.length) {      const top = q_start.shift();Â
      // if the topmost element is end      if (visited_end[top]) {        commonNode = top;        break;      }Â
      // perform multiplication with all array elements      for (let i = 0; i < a.length; i++) {        let pushed = top * a[i];        pushed = pushed % mod;Â
        // if not visited, then push it to queue        if (!visited_start[pushed]) {          ans_start[pushed] = ans_start[top] + 1;          q_start.push(pushed);          visited_start[pushed] = true;        }      }    } else {      const top = q_end.shift();Â
      // if the topmost element is start      if (visited_start[top]) {        commonNode = top;        break;      }Â
      // perform multiplication with all array elements      for (let i = 0; i < a.length; i++) {        let pushed = top * a[i];        pushed = pushed % mod;Â
        // if not visited, then push it to queue        if (!visited_end[pushed]) {          ans_end[pushed] = ans_end[top] + 1;          q_end.push(pushed);          visited_end[pushed] = true;        }      }    }  }Â
  if (commonNode === -1) {    return -1;  }Â
  // return the sum of minimum steps from start and end to common node  return ans_start[commonNode] + ans_end[commonNode];}Â
// Driver Codeconst start = 7;const end = 66175;const a = [3, 4, 65];let n = a.length;// Calling functionconsole.log(minimumMultiplications(start, end, a, n));Â
// The code is contributed by Arushi Goel. |
4
Time Complexity: O(n)
Auxiliary Space: O(n)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!


