Open In App

Maximize trailing zeros in product from top left to bottom right of given Matrix

Improve
Improve
Like Article
Like
Save
Share
Report

Given a matrix mat[][] of dimensions N * M
the task is to print the maximum number of trailing zeros that can be obtained in the product of matrix elements in the path from the top-left cell (0, 0) to the bottom-right cell (N – 1, M – 1) of the given matrix. Only possible moves from any cell (i, j) is (i + 1, j) or (i, j + 1).

Examples:

Input: N = 3, M = 4, mat[][] = {{6, 25, 4, 10}, {12, 25, 1, 15}, {7, 15, 15, 5}}
Output: 4
Explanation: Among all possible paths from top left to bottom right, the path (6, 25, 4, 10, 15, 5} has product (= 450000) with maximum number of trailing 0s. Therefore, the count of zeros is 4.

Input: N = 3, M = 3, mat[][] = {{2, 5, 2}, {10, 2, 40}, {5, 4, 8}}
Output: 2

Naive Approach: The idea is to generate all possible paths from the top-left cell (0, 0) to the bottom-right cell (N – 1, M – 1) of the given matrix recursively and calculate the product of elements in each path. Print the maximum no of trailing zeros among the products. Follow the steps below to solve the problem:

  • Initialize a variable, say product to store the product of all possible elements on the path from the top-left cell (0, 0) to bottom-right cell (N – 1, M – 1).
  • Below recurrence relation calculates the maxZeros value of all possible paths from the top-left cell (0, 0) to the bottom-right cell (N – 1, M – 1).

maxZeros(i, j, productValue) = max(maxZeros(i – 1, j, product*mat[i][j]), maxZeros(i, j – 1, product*mat[i][j]))
where, 
maxZeros() is the function that returns the maximum number of trailing zeros.

  • From the above recurrence relation generate all possible path recursively and when any path reaches the cell (N – 1, M – 1) then find the count of trailing zeros of the product till that path.
  • When every recursive call ends, maximize the count of zeros returns by that recursive calls.
  • Print the maximum number of trailing zeros after the above steps.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
#define N 3
#define M 4
 
// Stores the maximum count of zeros
int zeros = 0;
 
// Function that counts the trailing
// zeros in the given number num
int countZeros(int num)
{
     
    // Stores the count of zeros
    int count = 0;
 
    // Iterate digits of num
    while (num > 0 && num % 10 == 0)
    {
        num /= 10;
        count++;
    }
 
    // Return the count
    return count;
}
 
// Function to count maximum trailing
// zeros in product of elements in a
// path from top-left to bottom-right
void maxZeros(int mat[][M], int i,
              int j, int product)
{
     
    // If reached end of matrix
    if (i == N - 1 && j == M - 1)
    {
         
        // Count the no of zeros product
        product *= mat[i][j];
        zeros = max(zeros, countZeros(product));
        return;
    }
 
    // If out of bounds, return
    if (i >= N)
        return;
    if (j >= M)
        return;
 
    // Recurse with move (i+1, j)
    maxZeros(mat, i + 1, j,
            product * mat[i][j]);
 
    // Recurse with  move(i, j+1)
    maxZeros(mat, i, j + 1,
               product * mat[i][j]);
}
 
// Function to print the maximum
// count of trailing zeros obtained
void maxZerosUtil(int mat[][M], int i,
                  int j, int product)
{
     
    // Function Call
    maxZeros(mat, 0, 0, 1);
 
    // Print the maximum count
    cout << zeros << endl;
}
 
// Driver Code
int main()
{
     
    // Given matrix
    int mat[N][M] = { { 6, 25, 4, 10 },
                      { 12, 25, 1, 15 },
                      { 7, 15, 15, 5 } };
 
    // Function Call
    maxZerosUtil(mat, 0, 0, 1);
}
 
// This code is contributed by bolliranadheer


Java




// Java program for the above approach
 
import java.util.*;
class GFG {
 
    // Stores the maximum count of zeros
    static int zeros = 0;
 
    // Function to count maximum trailing
    // zeros in product of elements in a
    // path from top-left to bottom-right
    public static void maxZeros(int[][] mat,
                                int i, int j,
                                int product)
    {
        // If reached end of matrix
        if (i == mat.length - 1
            && j == mat[0].length - 1) {
 
            // Count the no of zeros product
            product *= mat[i][j];
            zeros = Math.max(zeros,
                             countZeros(product));
            return;
        }
 
        // If out of bounds, return
        if (i >= mat.length)
            return;
        if (j >= mat[0].length)
            return;
 
        // Recurse with move (i+1, j)
        maxZeros(mat, i + 1, j,
                 product * mat[i][j]);
 
        // Recurse with  move(i, j+1)
        maxZeros(mat, i, j + 1,
                 product * mat[i][j]);
    }
 
    // Function that counts the trailing
    // zeros in the given number num
    public static int countZeros(int num)
    {
        // Stores the count of zeros
        int count = 0;
 
        // Iterate digits of num
        while (num > 0 && num % 10 == 0) {
 
            num /= 10;
            count++;
        }
 
        // Return the count
        return count;
    }
 
    // Function to print the maximum
    // count of trailing zeros obtained
    public static void maxZerosUtil(
        int[][] mat, int i, int j, int product)
    {
 
        // Function Call
        maxZeros(mat, 0, 0, 1);
 
        // Print the maximum count
        System.out.println(zeros);
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        // Given N & M
        int N = 3, M = 4;
 
        // Given matrix
        int mat[][] = { { 6, 25, 4, 10 },
                        { 12, 25, 1, 15 },
                        { 7, 15, 15, 5 } };
 
        // Function Call
        maxZerosUtil(mat, 0, 0, 1);
    }
}


Python3




# Python3 program for the
# above approach
N = 3
M = 4
 
# Stores the maximum count
# of zeros
zeros = 0
 
# Function that counts the
# trailing zeros in the
# given number num
def countZeros(num):
 
    #  Stores the count of
    #zeros
    count = 0
 
    # Iterate digits of
    # num
    while (num > 0 and
           num % 10 == 0):
        num //= 10
        count += 1
 
    # Return the count
    return count
 
# Function to count maximum
# trailing zeros in product
# of elements in a path from
# top-left to bottom-right
def maxZeros(mat, i,
             j, product):
   
    global M
    global N
 
    # If reached end of
    # matrix
    if (i == N - 1 and
        j == M - 1):
 
        # Count the no of
        # zeros product
        product *= mat[i][j]
        global zeros
        zeros = max(zeros,
                    countZeros(product))
        return
 
    # If out of bounds,
    # return
    if (i >= N):
        return
    if (j >= M):
        return
 
    # Recurse with move
    # (i+1, j)
    maxZeros(mat, i + 1, j,
             product * mat[i][j])
 
    # Recurse with move
    # (i, j+1)
    maxZeros(mat, i, j + 1,
             product * mat[i][j])
 
# Function to print the
# maximum count of trailing
# zeros obtained
def maxZerosUtil(mat, i,
                 j, product):
 
    # Function Call
    maxZeros(mat, 0, 0, 1)
 
    # Print the maximum
    # count
    print(zeros)
 
# Driver Code
if __name__ == "__main__":
 
    # Given matrix
    mat = [[6, 25, 4, 10],
           [12, 25, 1, 15],
           [7, 15, 15, 5]]
 
    # Function Call
    maxZerosUtil(mat, 0, 0, 1)
 
# This code is contributed by Chitranayal


C#




// C# program for the above approach
using System;
 
class GFG{
 
// Stores the maximum count of zeros
static int zeros = 0;
 
// Function to count maximum trailing
// zeros in product of elements in a
// path from top-left to bottom-right
public static void maxZeros(int[,] mat,
                            int i, int j,
                            int product,
                            int N, int M)
{
     
    // If reached end of matrix
    if (i == N - 1 && j == M - 1)
    {
         
        // Count the no of zeros product
        product *= mat[i, j];
        zeros = Math.Max(zeros,
                         countZeros(product));
        return;
    }
 
    // If out of bounds, return
    if (i >= mat.GetLength(0))
        return;
    if (j >= mat.GetLength(1))
        return;
 
    // Recurse with move (i+1, j)
    maxZeros(mat, i + 1, j,
             product * mat[i, j], N, M);
 
    // Recurse with  move(i, j+1)
    maxZeros(mat, i, j + 1,
             product * mat[i, j], N, M);
}
 
// Function that counts the trailing
// zeros in the given number num
public static int countZeros(int num)
{
     
    // Stores the count of zeros
    int count = 0;
 
    // Iterate digits of num
    while (num > 0 && num % 10 == 0)
    {
        num /= 10;
        count++;
    }
 
    // Return the count
    return count;
}
 
// Function to print the maximum
// count of trailing zeros obtained
public static void maxZerosUtil(int[,] mat, int i,
                                int j, int product,
                                int N, int M)
{
     
    // Function Call
    maxZeros(mat, 0, 0, 1, N, M);
 
    // Print the maximum count
    Console.WriteLine(zeros);
}
 
// Driver Code
public static void Main(String[] args)
{
     
    // Given N & M
    int N = 3, M = 4;
 
    // Given matrix
    int [,]mat = { { 6, 25, 4, 10 },
                   { 12, 25, 1, 15 },
                   { 7, 15, 15, 5 } };
 
    // Function Call
    maxZerosUtil(mat, 0, 0, 1, N, M);
}
}
 
// This code is contributed by Amit Katiyar


Javascript




<script>
 
// Javascript program for the above approach
 
var N = 3
var M = 4
 
// Stores the maximum count of zeros
var zeros = 0;
 
// Function that counts the trailing
// zeros in the given number num
function countZeros(num)
{
     
    // Stores the count of zeros
    var count = 0;
 
    // Iterate digits of num
    while (num > 0 && num % 10 == 0)
    {
        num /= 10;
        count++;
    }
 
    // Return the count
    return count;
}
 
// Function to count maximum trailing
// zeros in product of elements in a
// path from top-left to bottom-right
function maxZeros(mat, i, j, product)
{
     
    // If reached end of matrix
    if (i == N - 1 && j == M - 1)
    {
         
        // Count the no of zeros product
        product *= mat[i][j];
        zeros = Math.max(zeros, countZeros(product));
        return;
    }
 
    // If out of bounds, return
    if (i >= N)
        return;
    if (j >= M)
        return;
 
    // Recurse with move (i+1, j)
    maxZeros(mat, i + 1, j,
            product * mat[i][j]);
 
    // Recurse with  move(i, j+1)
    maxZeros(mat, i, j + 1,
               product * mat[i][j]);
}
 
// Function to print the maximum
// count of trailing zeros obtained
function maxZerosUtil(mat, i, j, product)
{
     
    // Function Call
    maxZeros(mat, 0, 0, 1);
 
    // Print the maximum count
    document.write( zeros + "<br>");
}
 
// Driver Code
// Given matrix
var mat = [ [ 6, 25, 4, 10 ],
            [ 12, 25, 1, 15 ],
            [ 7, 15, 15, 5 ]];
 
// Function Call
 
maxZerosUtil(mat, 0, 0, 1);
 
</script>


Output

4

Time Complexity: O(2N*M)
Auxiliary Space: O(1)

Dynamic Programming using Bottom-Up Approach: The recursive calls in the above approach can be reduced using an auxiliary array dp[][] and calculate the value of each state in the bottom-up approach. Follow the steps below:

  • Create an auxiliary array dp[][] of size N*M.
  • dp[i][j] represents no of fives and twos till the ith row and jth column.
  • Traverse the matrix and update each state of dp[][] array as:

dp[i][j] = max(dp[i – 1][j], dp[i][j – 1])

  • Print the minimum of the respective count of (2s, 5s) after the above steps as the result.

Below is the implementation of the above approach:

Java




// Java program for the above approach
 
import java.io.*;
import java.util.*;
 
// Create a class pair to store
// count of 2's and 5's
class pair {
    int x, y;
 
    // Parameterized Constructor
    pair(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
 
    // Function to convert into Strings
    public String toString()
    {
        return "(" + this.x + ", "
            + this.y + ")";
    }
}
 
class GFG {
 
    // Function to get maximum no of
    // zeros in product of path from
    // topleft to bottom right
    public static void maxZeros(
        int[][] mat, int n, int m)
    {
        // Base Case
        if (n == 0 || m == 0)
            return;
 
        // Store the maximum count of
        // zeros till ith and jth index
        pair dp[][] = new pair[n + 1][m + 1];
 
        // Initialize the (0, 0)
        dp[0][0] = new pair(countTwos(mat[0][0]),
                            countFives(mat[0][0]));
 
        // Initialize the first  row
        // and column explicitly
        for (int i = 1; i < n; i++)
            dp[i][0] = add(
                dp[i - 1][0],
                new pair(
                    countTwos(mat[i][0]),
                    countFives(mat[i][0])));
 
        for (int i = 1; i < m; i++)
            dp[0][i] = add(
                dp[0][i - 1],
                new pair(
                    countTwos(mat[0][i]),
                    countFives(mat[0][i])));
 
        // Iterate through all the cells
        for (int i = 1; i < n; i++) {
 
            for (int j = 1; j < m; j++) {
 
                // Get the pair from the
                // top and from left
                pair top = dp[i - 1][j];
                pair left = dp[i][j - 1];
 
                pair curr = new pair(
                    countTwos(mat[i][j]),
                    countFives(mat[i][j]));
                top = add(top, curr);
                left = add(left, curr);
 
                // If there are more number
                // of 0s from top or left
                if (check(top, left))
                    dp[i][j] = top;
                else
                    dp[i][j] = left;
            }
        }
 
        // Print the no of zeros
        // min(no of 2's, no of 5's)
        System.out.println(
            Math.min(dp[n - 1][m - 1].x,
                     dp[n - 1][m - 1].y));
    }
 
    // Function to calculate no of zeros
    public static boolean check(
        pair one, pair two)
    {
        int top = Math.min(one.x, one.y);
        int left = Math.min(two.x, two.y);
        if (top > left)
            return true;
        else
            return false;
    }
 
    // Function to calculate no of 2's
    public static int countTwos(int num)
    {
        int count = 0;
        while (num != 0 && num % 2 == 0) {
            num /= 2;
            count++;
        }
 
        // Return the final count
        return count;
    }
 
    // Function to calculate no of 5's
    public static int countFives(int num)
    {
        int count = 0;
        while (num != 0 && num % 5 == 0) {
            num /= 5;
            count++;
        }
 
        // Return the final count
        return count;
    }
 
    // Function to add pairs
    public static pair add(pair one,
                           pair two)
    {
        pair np = new pair(one.x + two.x,
                           one.y + two.y);
 
        // Return the resultant pair
        return np;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        // Given N & M
        int N = 3, M = 4;
 
        // Given matrix
        int mat[][] = { { 6, 25, 4, 10 },
                        { 12, 25, 1, 15 },
                        { 7, 15, 15, 5 } };
 
        // Function Call
        maxZeros(mat, N, M);
    }
}


Python3




#Python code for the above approach
import math
 
# Create a class pair to store
# count of 2's and 5's
class pair:
    def __init__(self, x, y):
        self.x = x
        self.y = y
 
    # Function to convert into Strings
    def __str__(self):
        return "(" + str(self.x) + ", " + str(self.y) + ")"
 
 
# Function to get maximum no of
# zeros in product of path from
# topleft to bottom right
def maxZeros(mat, n, m):
    # Base Case
    if n == 0 or m == 0:
        return
 
    # Store the maximum count of
    # zeros till ith and jth index
    dp = [[0 for _ in range(m + 1)] for _ in range(n + 1)]
 
    # Initialize the (0, 0)
    dp[0][0] = pair(countTwos(mat[0][0]), countFives(mat[0][0]))
 
    # Initialize the first row and column explicitly
    for i in range(1, n):
        dp[i][0] = add(dp[i - 1][0], pair(countTwos(mat[i][0]), countFives(mat[i][0])))
 
    for i in range(1, m):
        dp[0][i] = add(dp[0][i - 1], pair(countTwos(mat[0][i]), countFives(mat[0][i])))
 
    # Iterate through all the cells
    for i in range(1, n):
        for j in range(1, m):
            # Get the pair from the top and from left
            top = dp[i - 1][j]
            left = dp[i][j - 1]
 
            curr = pair(countTwos(mat[i][j]), countFives(mat[i][j]))
            top = add(top, curr)
            left = add(left, curr)
 
            # If there are more number of 0s from top or left
            if check(top, left):
                dp[i][j] = top
            else:
                dp[i][j] = left
 
    # Print the no of zeros
    # min(no of 2's, no of 5's)
    print(min(dp[n - 1][m - 1].x, dp[n - 1][m - 1].y))
 
 
# Function to calculate no of zeros
def check(one, two):
    top = min(one.x, one.y)
    left = min(two.x, two.y)
    if top > left:
        return True
    else:
        return False
 
 
# Function to calculate no of 2's
def countTwos(num):
    count = 0
    while num != 0 and num % 2 == 0:
        num /= 2
        count += 1
 
    # Return the final count
    return count
 
 
# Function to calculate no of 5's
def countFives(num):
    count = 0
    while num != 0 and num % 5 == 0:
        num /= 5
        count += 1
         
    return count
 
# Function to add pairs
def add(one, two):
    np = pair(one.x + two.x, one.y + two.y)
    return np
 
# test the code with a matrix
# Given N & M
N = 3;
M = 4;
#Given matrix
mat = [[6, 25, 4, 10], [12, 25, 1, 15], [7, 15, 15, 5]];
# Function Call
maxZeros(mat, N, M);


C#




// C# program for the above approach
using System;
 
// Create a class pair to store
// count of 2's and 5's
public class pair
{
    public int x, y;
     
    // Parameterized Constructor
    public pair(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
 
    // Function to convert into Strings
    public String toString()
    {
        return "(" + this.x + ", " +
                     this.y + ")";
    }
}
 
class GFG{
 
// Function to get maximum no of
// zeros in product of path from
// topleft to bottom right
public static void maxZeros(int[,] mat, int n,
                                        int m)
{
     
    // Base Case
    if (n == 0 || m == 0)
        return;
 
    // Store the maximum count of
    // zeros till ith and jth index
    pair [,]dp = new pair[n + 1, m + 1];
 
    // Initialize the (0, 0)
    dp[0, 0] = new pair(countTwos(mat[0, 0]),
                       countFives(mat[0, 0]));
 
    // Initialize the first  row
    // and column explicitly
    for(int i = 1; i < n; i++)
        dp[i, 0] = add(dp[i - 1, 0],
                   new pair(
                       countTwos(mat[i, 0]),
                       countFives(mat[i, 0])));
 
    for(int i = 1; i < m; i++)
        dp[0, i] = add(dp[0, i - 1],
                   new pair(
                       countTwos(mat[0, i]),
                       countFives(mat[0, i])));
 
    // Iterate through all the cells
    for(int i = 1; i < n; i++)
    {
        for(int j = 1; j < m; j++)
        {
             
            // Get the pair from the
            // top and from left
            pair top = dp[i - 1, j];
            pair left = dp[i, j - 1];
 
            pair curr = new pair(
                countTwos(mat[i, j]),
                countFives(mat[i, j]));
                 
            top = add(top, curr);
            left = add(left, curr);
 
            // If there are more number
            // of 0s from top or left
            if (check(top, left))
                dp[i, j] = top;
            else
                dp[i, j] = left;
        }
    }
 
    // Print the no of zeros
    // min(no of 2's, no of 5's)
    Console.WriteLine(
        Math.Min(dp[n - 1, m - 1].x,
                 dp[n - 1, m - 1].y));
}
 
// Function to calculate no of zeros
public static bool check(pair one, pair two)
{
    int top = Math.Min(one.x, one.y);
    int left = Math.Min(two.x, two.y);
     
    if (top > left)
        return true;
    else
        return false;
}
 
// Function to calculate no of 2's
public static int countTwos(int num)
{
    int count = 0;
    while (num != 0 && num % 2 == 0)
    {
        num /= 2;
        count++;
    }
 
    // Return the readonly count
    return count;
}
 
// Function to calculate no of 5's
public static int countFives(int num)
{
    int count = 0;
    while (num != 0 && num % 5 == 0)
    {
        num /= 5;
        count++;
    }
 
    // Return the readonly count
    return count;
}
 
// Function to add pairs
public static pair add(pair one,
                       pair two)
{
    pair np = new pair(one.x + two.x,
                       one.y + two.y);
 
    // Return the resultant pair
    return np;
}
 
// Driver Code
public static void Main(String[] args)
{
     
    // Given N & M
    int N = 3, M = 4;
 
    // Given matrix
    int [,]mat = { { 6, 25, 4, 10 },
                   { 12, 25, 1, 15 },
                   { 7, 15, 15, 5 } };
 
    // Function Call
    maxZeros(mat, N, M);
}
}
 
// This code is contributed by Amit Katiyar


Javascript




<script>
// Create a class pair to store
// count of 2's and 5's
class pair
{
    x = 0;
    y = 0;
    // Parameterized Constructor
    constructor(x, y)
    {
        this.x = x;
        this.y = y;
    }
    // Function to convert into Strings
    toString()
    {
        return "(" + this.x + ", " + this.y + ")";
    }
}
class GFG
{
    // Function to get maximum no of
    // zeros in product of path from
    // topleft to bottom right
    static maxZeros(mat, n, m)
    {
        // Base Case
        if (n == 0 || m == 0)
        {
            return;
        }
        // Store the maximum count of
        // zeros till ith and jth index
        var dp = Array(n + 1).fill(null).map(()=>new Array(m + 1).fill(null));
        // Initialize the (0, 0)
        dp[0][0] = new pair(GFG.countTwos(mat[0][0]), GFG.countFives(mat[0][0]));
        // Initialize the first  row
        // and column explicitly
        for (let i=1; i < n; i++)
        {
            dp[i][0] = GFG.add(dp[i - 1][0], new pair(GFG.countTwos(mat[i][0]), GFG.countFives(mat[i][0])));
        }
        for (let i=1; i < m; i++)
        {
            dp[0][i] = GFG.add(dp[0][i - 1], new pair(GFG.countTwos(mat[0][i]), GFG.countFives(mat[0][i])));
        }
        // Iterate through all the cells
        for (let i=1; i < n; i++)
        {
            for (let j=1; j < m; j++)
            {
                // Get the pair from the
                // top and from left
                var top = dp[i - 1][j];
                var left = dp[i][j - 1];
                var curr = new pair(GFG.countTwos(mat[i][j]), GFG.countFives(mat[i][j]));
                top = GFG.add(top, curr);
                left = GFG.add(left, curr);
                // If there are more number
                // of 0s from top or left
                if (GFG.check(top, left))
                {
                    dp[i][j] = top;
                }
                else
                {
                    dp[i][j] = left;
                }
            }
        }
        // Print the no of zeros
        // min(no of 2's, no of 5's)
        document.write(Math.min(dp[n - 1][m - 1].x,dp[n - 1][m - 1].y));
    }
    // Function to calculate no of zeros
    static check(one, two)
    {
        var top = Math.min(one.x,one.y);
        var left = Math.min(two.x,two.y);
        if (top > left)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    // Function to calculate no of 2's
    static countTwos(num)
    {
        var count = 0;
        while (num != 0 && num % 2 == 0)
        {
            num /= 2;
            count++;
        }
        // Return the final count
        return count;
    }
    // Function to calculate no of 5's
    static countFives(num)
    {
        var count = 0;
        while (num != 0 && num % 5 == 0)
        {
            num /= 5;
            count++;
        }
        // Return the final count
        return count;
    }
    // Function to add pairs
    static add(one, two)
    {
        var np = new pair(one.x + two.x, one.y + two.y);
        // Return the resultant pair
        return np;
    }
    // Driver Code
    static main(args)
    {
        // Given N & M
        var N = 3;
        var M = 4;
        // Given matrix
        var mat = [[6, 25, 4, 10], [12, 25, 1, 15], [7, 15, 15, 5]];
        // Function Call
        GFG.maxZeros(mat, N, M);
    }
}
GFG.main([]);
</script>


C++




// C++ program for the above approach
#include <iostream>
#include <utility>
using namespace std;
 
// Create a class pair to store
// count of 2's and 5's
class Pair {
public:
    int x, y;
    Pair()
        : x(0)
        , y(0)
    {
    }
    // Parameterized Constructor
    Pair(int x, int y)
    {
        this->x = x;
        this->y = y;
    }
 
    // Function to convert into Strings
    string toString()
    {
        return "(" + to_string(this->x) + ", "
               + to_string(this->y) + ")";
    }
};
 
// Function to calculate no of zeros
bool check(Pair one, Pair two)
{
    int top = min(one.x, one.y);
    int left = min(two.x, two.y);
    return top > left;
}
 
// Function to calculate no of 2's
int countTwos(int num)
{
    int count = 0;
    while (num != 0 && num % 2 == 0) {
        num /= 2;
        count++;
    }
    // Return the final count
    return count;
}
 
// Function to calculate no of 5's
int countFives(int num)
{
    int count = 0;
    while (num != 0 && num % 5 == 0) {
        num /= 5;
        count++;
    }
    // Return the final count
    return count;
}
 
// Function to add pairs
Pair add(Pair one, Pair two)
{
    Pair np(one.x + two.x, one.y + two.y);
    // Return the resultant pair
    return np;
}
 
// Function to get maximum no of
// zeros in product of path from
// topleft to bottom right
void maxZeros(int mat[][4], int n, int m)
{
    // base case
    if (n == 0 || m == 0)
        return;
 
    // Store the maximum count of
    // zeros till ith and jth index
    Pair dp[n + 1][m + 1];
 
    // Initialize the (0, 0)
    dp[0][0]
        = Pair(countTwos(mat[0][0]), countFives(mat[0][0]));
 
    // Initialize the first  row
    // and column explicitly
    for (int i = 1; i < n; i++)
        dp[i][0] = add(dp[i - 1][0],
                       Pair(countTwos(mat[i][0]),
                            countFives(mat[i][0])));
    for (int i = 1; i < m; i++)
        dp[0][i] = add(dp[0][i - 1],
                       Pair(countTwos(mat[0][i]),
                            countFives(mat[0][i])));
 
    // Iterate through all the cells
    for (int i = 1; i < n; i++) {
        for (int j = 1; j < m; j++) {
            // Get the pair from the
            // top and from left
            Pair top = dp[i - 1][j];
            Pair left = dp[i][j - 1];
            Pair curr(countTwos(mat[i][j]),
                      countFives(mat[i][j]));
            top = add(top, curr);
            left = add(left, curr);
 
            // If there are more number
            // of 0s from top or left
            if (check(top, left))
                dp[i][j] = top;
            else
                dp[i][j] = left;
        }
    }
 
    // Print the no of zeros
    // min(no of 2's, no of 5's)
    cout << min(dp[n - 1][m - 1].x, dp[n - 1][m - 1].y)
         << endl;
}
 
int main()
{
    // Given N & M
    int N = 3, M = 4;
 
    // Given matrix
    int mat[][4] = { { 6, 25, 4, 10 },
                     { 12, 25, 1, 15 },
                     { 7, 15, 15, 5 } };
 
    // Function Call
    maxZeros(mat, N, M);
    return 0;
}
 
// contributed by sdeadityasharma


Output

4

Time Complexity: O(N*M*log10(maxE)), where maxE is the maximum value in the given matrix.
Auxiliary Space: O(N*M)



Last Updated : 20 Mar, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads