📌  相关文章
📜  从给定矩阵的左上到右下最大化乘积的尾随零

📅  最后修改于: 2021-04-29 01:14:03             🧑  作者: Mango

给定尺寸为N * M的矩阵mat [] []
该任务是打印从左上单元格(0,0)到右下单元格(N – 1,M – 1)的路径中矩阵元素乘积所能获得的最大尾随零数。给定矩阵的来自任何像元(i,j)的唯一可能移动是(i + 1,j)(i,j + 1)。

例子:

天真的方法:想法是递归生成给定矩阵的从左上角单元(0,0)到右下角单元(N – 1,M – 1)的所有可能路径,并计算每个元素的乘积小路。打印产品之间最大的尾随零数。请按照以下步骤解决问题:

  • 初始化一个变量,例如乘积,以存储从左上单元格(0,0)到右下单元格(N – 1,M – 1)的路径上所有可能元素的乘积。
  • 下面的递归关系计算从左上单元格(0,0)到右下单元格(N – 1,M – 1)的所有可能路径的maxZeros值。
  • 从上述递归关系中,递归地生成所有可能的路径,当任何路径到达单元格(N – 1,M – 1)时,然后求出该路径之前乘积的尾随零的计数。
  • 当每个递归调用结束时,该递归调用将最大返回零计数。
  • 完成上述步骤后,输出最大的尾随零。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
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


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 covert 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);
    }
}


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 covert 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


输出
4



时间复杂度: O(2 N * M )
辅助空间: O(1)

使用自底向上方法的动态编程可以使用辅助数组dp [] []减少上述方法中的递归调用,并在自底向上方法中计算每个状态的值。请按照以下步骤操作:

  • 创建一个大小为N * M的辅助数组dp [] []
  • dp [i] [j]代表第5行和第2行中的i行,直到第i列和j列为止。
  • 遍历矩阵并将dp [] []数组的每个状态更新为:
  • 在执行上述步骤后打印出相应的最小计数(2s,5s)作为结果。

下面是上述方法的实现:

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 covert 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);
    }
}

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 covert 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
输出
4



时间复杂度: O(N * M * log 10 (maxE)),其中maxE是给定矩阵中的最大值。
辅助空间: O(N * M)