2023-03-26:给定一个二维数组matrix,
每个格子都是正数,每个格子都和上、下、左、右相邻。
你可以从任何一个格子出发,走向相邻的格子,
把沿途的数字乘起来,希望得到的最终数字中,结尾的0最多,
走的过程中,向左走或者向右走的拐点,最多只能有一次。
返回结尾最多的0,能是多少。
1 <= 行、列 <= 400。

答案2023-03-26:

解题思路

本题需要求出从任意位置出发,最多能有多少个结尾0。为了方便计算,可以先将矩阵中每个数分解成2和5的因子,然后通过前缀和预处理出每个位置上、左方向的2和5的因子数量之和,以便快速计算6个方向上的因子数量之和。接着遍历每个位置,分别计算6个方向上的因子数量之和,并取其中的最小值,最后返回所有最小值中的最大值即可。

具体来说,对于一个位置(i,j),可以计算它的左、右、上、下4个方向的2和5的因子数量之和,以及两个斜方向的2和5的因子数量之和共6个值。然后取这6个值中的最小值,就是从该位置出发,在该方向上能够得到的最多结尾0的数量。遍历所有位置,取最大值即可。

需要注意的是,由于只能有一次向左或向右的拐点,因此在计算左和右方向上的因子数量之和时,需要分别计算到该行左边界和右边界的因子数量之和,然后再通过减法计算出中间部分的因子数量之和。

时间复杂度

本算法需要对矩阵中每个数进行分解质因数,时间复杂度为O(n ^ 2log(max(matrix)));两层循环分别对n和m进行遍历,时间复杂度为O(nm);因此总时间复杂度为O(n^2log(max(matrix))+nm)。

空间复杂度

本算法需要维护4个二维数组,每个数组的大小均为n×m,因此空间复杂度为O(nm)。

rust代码

fn most_trailing_zeros(matrix: &Vec<Vec<i32>>) -> i32 {
let n = matrix.len(); // 矩阵行数
let m = matrix[0].len(); // 矩阵列数 // f2[i][j] : matrix[i][j]自己有几个2的因子
let mut f2 = vec![vec![0; m]; n];
// f5[i][j] : matrix[i][j]自己有几个5的因子
let mut f5 = vec![vec![0; m]; n]; // 预处理每个位置的2和5的因子数量
for i in 0..n {
for j in 0..m {
f2[i][j] = factors(matrix[i][j], 2);
f5[i][j] = factors(matrix[i][j], 5);
}
} // 计算每个位置上、左方向的2和5的因子数量之和
let mut left_f2 = vec![vec![0; m]; n];
let mut left_f5 = vec![vec![0; m]; n];
let mut up_f2 = vec![vec![0; m]; n];
let mut up_f5 = vec![vec![0; m]; n]; for i in 0..n {
for j in 0..m {
left_f2[i][j] = f2[i][j] + if j > 0 { left_f2[i][j - 1] } else { 0 };
left_f5[i][j] = f5[i][j] + if j > 0 { left_f5[i][j - 1] } else { 0 };
up_f2[i][j] = f2[i][j] + if i > 0 { up_f2[i - 1][j] } else { 0 };
up_f5[i][j] = f5[i][j] + if i > 0 { up_f5[i - 1][j] } else { 0 };
}
} let mut ans = 0;
for i in 0..n {
for j in 0..m {
// 来到(i,j),计算6个方向上的因子数量之和
let l2 = if j == 0 { 0 } else { left_f2[i][j - 1] }; // 左边的2因子数量之和
let l5 = if j == 0 { 0 } else { left_f5[i][j - 1] }; // 左边的5因子数量之和
let r2 = left_f2[i][m - 1] - left_f2[i][j]; // 右边的2因子数量之和
let r5 = left_f5[i][m - 1] - left_f5[i][j]; // 右边的5因子数量之和
let u2 = if i == 0 { 0 } else { up_f2[i - 1][j] }; // 上面的2因子数量之和
let u5 = if i == 0 { 0 } else { up_f5[i - 1][j] }; // 上面的5因子数量之和
let d2 = up_f2[n - 1][j] - up_f2[i][j]; // 下面的2因子数量之和
let d5 = up_f5[n - 1][j] - up_f5[i][j]; // 下面的5因子数量之和 // 计算6个方向上因子数量之和最小的值
let p1 = std::cmp::min(l2 + u2 + f2[i][j], l5 + u5 + f5[i][j]);
let p2 = std::cmp::min(l2 + r2 + f2[i][j], l5 + r5 + f5[i][j]);
let p3 = std::cmp::min(l2 + d2 + f2[i][j], l5 + d5 + f5[i][j]);
let p4 = std::cmp::min(u2 + r2 + f2[i][j], u5 + r5 + f5[i][j]);
let p5 = std::cmp::min(u2 + d2 + f2[i][j], u5 + d5 + f5[i][j]);
let p6 = std::cmp::min(r2 + d2 + f2[i][j], r5 + d5 + f5[i][j]); // 取6个方向上的最小值中的最大值作为答案
ans = std::cmp::max(
ans,
std::cmp::max(
std::cmp::max(p1, p2),
std::cmp::max(std::cmp::max(p3, p4), std::cmp::max(p5, p6)),
),
);
}
} ans
} // 计算num有几个f的因子
fn factors(num: i32, f: i32) -> i32 {
let mut ans = 0;
let mut num = num; while num % f == 0 {
ans += 1;
num /= f;
} ans
} fn main() {
let matrix1 = vec![
vec![5, 8, 3, 1],
vec![4, 15, 12, 1],
vec![6, 7, 10, 1],
vec![9, 1, 2, 1],
];
println!("{}", most_trailing_zeros(&matrix1)); // 输出:2 let matrix2 = vec![
vec![7500, 10, 11, 12],
vec![6250, 13, 14, 15],
vec![134, 17, 16, 1],
vec![5500, 2093, 5120, 238],
];
println!("{}", most_trailing_zeros(&matrix2)); // 输出:13
}

运行结果

2023-03-26:给定一个二维数组matrix, 每个格子都是正数,每个格子都和上、下、左、右相邻。 你可以从任何一个格子出发,走向相邻的格子, 把沿途的数字乘起来,希望得到的最终数字中,结尾的0的更多相关文章

  1. ytu 1050:写一个函数,使给定的一个二维数组(3×3)转置,即行列互换(水题)

    1050: 写一个函数,使给定的一个二维数组(3×3)转置,即行列互换 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 154  Solved: 112[ ...

  2. [CareerCup] 13.10 Allocate a 2D Array 分配一个二维数组

    13.10 Write a function in C called my2DAlloc which allocates a two-dimensional array. Minimize the n ...

  3. new一个二维数组

    .定义一个二维数组 char **array1 array1 = new char *[x]; for(i=0;i<x;++i) array1[i] = new char[y]; ...用的时候 ...

  4. c语言题目:找出一个二维数组的“鞍点”,即该位置上的元素在该行上最大,在该列上最小。也可能没有鞍点

    //题目:找出一个二维数组的“鞍点”,即该位置上的元素在该行上最大,在该列上最小.也可能没有鞍点. // #include "stdio.h" #include <stdli ...

  5. php中向前台js中传送一个二维数组

    在php中向前台js中传送一个二维数组,并在前台js接收获取其中值的全过程方法: (1),方法说明:现在后台将数组发送到前台 echo json_encode($result); 然后再在js页面中的 ...

  6. JAVA生成一个二维数组,使中间元素不与相邻的9个元素相等,并限制每一个元素的个数

    JAVA生成一个二维数组,使中间元素不与相邻的9个元素相等,并限制每一个元素的个数 示例如下 至少需要九个元素:"A","B","C",&q ...

  7. 如何用一个for循环打印出一个二维数组

    思路分析: 二维数组在内存中默认是按照行存储的,比如一个二维数组{{1,2,3,},{4,5,6}},它在内存中存储的顺序就是1.2.3.4.5.6,也就是说,对于这6个数组元素,按照从0到5给它们编 ...

  8. C语言程序,找出一个二维数组的鞍点。

    什么是鞍点????? 鞍点就是在一个二维数组中,某一个数在该行中最大,然而其在该列中又是最小的数,这样的数称为鞍点. 昨天突然在书上看到这样的一道题,就自己尝试着写了一个找出一个二维数组中的鞍点. 好 ...

  9. <转载>c++中new一个二维数组

    原文连接 在c++中定义一个二维数组时有多种方式,下面是几种定义方式的说明:其中dataType 表示数据类型,如int  byte  long... 1.dataType (*num)[n] = n ...

  10. C#编写程序,找一找一个二维数组中的鞍点

    编写程序,找一找一个二维数组中的鞍点(即该位置上的元素值在行中最大,在该列上最小.有可能数组没有鞍点).要求: 1.二维数组的大小.数组元素的值在运行时输入: 2.程序有友好的提示信息. 代码: us ...

随机推荐

  1. java锁之初相见

    废话不多说,先上锁的分类图 1.乐观锁&悲观锁 悲观锁 悲观锁认为自己在使用数据的时候一定有别的线程来修改数据,因此在获取数据的时候会先加锁,把别的线程阻塞住,最终确保数据不会被别的线程修改. ...

  2. vue几种插槽的使用方法

    参考文档:https://blog.csdn.net/weixin_49217200/article/details/118496525 参考文档:https://blog.csdn.net/ct52 ...

  3. MySQL 导出数据结构 If you don't want to restore GTIDs, pass --set-gtid-purged=OFF.

    应用场景MYSQL导出数据结构 Warning: A partial dump from a server that has GTIDs will by default include the GTI ...

  4. RecyclerView显示列表

    本次要讲的内容是利用RecyclerView显示Users列表的信息,如下图所示. 首先我们来创建模型User.java package com.example.mytest.User; import ...

  5. 代码大全_V2(1,2章笔记)

    译序 这本书讲什么 代码大全 原名叫 code complete,它是什么,又不是什么? 不是IDE中的代码自动补全功能 不是软件源代码 "大全" 是 "编码完成&quo ...

  6. Insecure Randomness 不安全的随机数

    Insecure Randomness Abstract 标准的伪随机数生成器不能抵挡各种加密攻击. Explanation 在对安全性要求较高的环境中,使用一个能产生可预测数值的函数作为随机数据源, ...

  7. 【读书笔记】格子路径计数LatticePathEnumeration 学一半的笔记

    流水账流水账这篇什么都不是 目录 方法 10.2 Lattice paths without restrictions 无限制格子路径 2维的例子,从(a,b)到(c,d),允许(0,1)和(1,0) ...

  8. Python3.10 的开发环境的搭建

    安装 下载 Python3.10 或者其他版本:Download Python | Python.org 如果 Windows 操作系统下载,默认是下载 64 位操作系统的 exe 安装包:pytho ...

  9. 原型继承和 Class 继承

    涉及面试题: 原型如何实现继承? Class 如何实现继承? Class 本质是什么? ⾸先先来讲下 class ,其实在 JS 中并不存在类, class 只是语法糖,本质还是函数. class P ...

  10. kafka rebalance你真的了解吗

    介绍 今天主要分享一下 kafka 的 rebalance,在 kafka 中,rebalance 是一个十分重要的概念,很多时候引发的一些问题可能都是由于 rebalance 引起的,rebalan ...