有趣的算法题之矩阵的特别乘积

news2024/11/23 20:16:44

矩阵元素相乘

        A[ n, m ] 是一个 n 行 m 列的矩阵,a[ i, j ] 表示 A 的第 i 行 j 列的元素,定义 x[ i , j ] 为 A 的第 i 行和第 j 列除了 a[ i, j ] 之外所有元素(共 n + m - 2 个)的乘积,即 x[ i, j ] = a[ i, 1 ] * a[ i, 2 ] * ... * a[ i, j-1 ] * ... * a[ i, m ] * a[ 1, j ] * a[ 2, j ] * ... * a[ i-1, j ] * a[ i+1, j ] * ...* a[ n, j ] 。现输入非负整形的矩阵 A[ n, m ] ,求 MAX( x[ i, j ] ),即所有的 x[ i, j ] 中的最大值

原题链接:矩阵元素相乘_牛客题霸_牛客网 (nowcoder.com)

格式

输入描述:第一行两个整数 n 和 m 。之后 n 行输入矩阵,均为非负整数。

输出描述:一行输出答案。

样例

输入:3 5
           5 1 8 5 2
           1 3 10 3 3
           7 8 5 5 16

输出:358400

思路分析

        首先,我们需要理解题目中的 x[i,j] 是什么。它表示的是矩阵 A 的第 i 行和第 j 列中除了 a[i,j] 之外的所有元素的乘积。那么,我们可以思考,如何高效地计算出每一个 x[i,j] 的值,而不需要对每个 x[i,j] 都进行 n+m-2 次乘法操作。

        观察 x[i,j] 的定义,我们可以发现,它其实是由两部分乘积构成的:一部分是第 i 行的所有元素的乘积除以 a[i,j],另一部分是第 j 列的所有元素的乘积除以 a[i,j]。如果我们能够提前计算出每一行和每一列的乘积,那么计算 x[i,j] 就会变得非常简单。

int num = (row[i]/arr[i][j])*(col[j]/arr[i][j]);

        但是,这里有一个特殊情况需要注意:如果 a[i,j] 是 0 ,但是,我们不能简单地将包含 0 的行或列的乘积设为 0 ,因为其他位置的 x[i,j] 可能还需要用到这些乘积(只是不包括 a[i,j] 为 0 的那个位置)。因此我们遇到这种情况应该跳过去

for (int i = 0;i < n;i++) {
    for (int j = 0;j < m;j++) {
        arr[i][j] = in.nextInt();
        // 计算行列 0 的个数,为 0 时不算入乘积
        if (arr[i][j] == 0) {
            row0[i]++;
            col0[j]++;
        }else {
            row[i]*= arr[i][j];
            col[j]*= arr[i][j];
        }
    }
}

        当行列的乘积都求取完毕后,我们开始遍历矩阵求取 x[i,j] ,而这时,我们又会遇到 a[i,j] 为 0 的情况,它会导致我们计算 x[i,j] 时出现除以 0 的操作,因此我们这里需要分情况去计算。

// 虽然 arr[i][j] 不参与计算,但它可能作为 0 出现在被除数中,因此分开计算
if (arr[i][j] == 0) {
    ans = Math.max(ans, row[i]*col[j]);
}else {
    ans = Math.max(ans, (row[i]/arr[i][j])*(col[j]/arr[i][j]));
}

        到这里,我们可以发现有个问题,因为前面计算乘积时都是遇到 0 就跳过去的,虽然 a[i,j] 并不是 x[i,j] 的因子,它是否为 0 我们并不用担心,但是如果行列乘积中除了 a[i,j] 存在其他因子为 0 时,我们又怎么去判断这种情况?我们可以想到,我们只需要去计算行列乘积时因子出现 0 的次数,再减去两倍 a[i,j] 为 0 的次数,就能得到 x[i,j] 因子为 0 的个数了。因此,我们需要分别记录每一行和每一列中 0 的个数

int [] row0 = new int[n]; // 存储每一行有几个 0
int [] col0 = new int[m]; // 存储每一列有几个 0
Arrays.fill(row, 1); // 将存储乘积的两个数组的值都赋为 1,便于计算乘积
Arrays.fill(col, 1);

具体步骤:

  1. 初始化两个数组 row 和 col,分别用于存储每一行和每一列(除了当前位置元素外)的乘积。同时,初始化两个数组 row0 和 col0,用于记录每一行和每一列中 0 的个数。

  2. 遍历矩阵 A ,填充 arr 数组,并同时更新 rowcolrow0 和 col0 数组。对于 arr[i][j],如果它是 0 ,则增加 row0[i] 和 col0[j] 的计数;否则,将其乘到 row[i] 和 col[j] 上。

  3. 遍历矩阵 A ,计算每个 x[i,j] 的值。对于每个位置 (i,j),首先检查 row0[i] 和 col0[j] 的和。如果这个和大于 0 ,说明至少有一行或一列包含 0 ,因此 x[i,j] 应该是0(因为至少有一个因子是 0 )。如果这个和等于 0 ,说明既没有行也没有列包含 0 ,此时我们可以根据 row[i] 和 col[j] 来计算 x[i,j] 的值。但是,需要注意的是,如果 arr[i][j] 本身为 0 时,我们还需要将它从 row[i] 和 col[j] 中除去,因为 x[i,j] 的定义中不包括 a[i,j]

  4. 在计算过程中,不断更新最大值 ans

代码

import java.util.Scanner;
import java.util.*;

public class Main {


    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 题目会读入多组数据,while 循环读取输入
        while (in.hasNextInt()) {
            int n = in.nextInt(); // 矩阵行数
            int m = in.nextInt(); // 矩阵列数
            int [][] arr = new int[n][m];
            int [] row = new int[n]; // 存储每一行除 0 外其他数的乘积
            int [] col = new int[m]; // 存储每一列除 0 外其他数的乘积
            int [] row0 = new int[n]; // 存储每一行有几个 0
            int [] col0 = new int[m]; // 存储每一列有几个 0
            Arrays.fill(row, 1); // 将存储乘积的两个数组的值都赋为 1,便于计算乘积
            Arrays.fill(col, 1);

            // 存储值
            for (int i = 0;i < n;i++) {
                for (int j = 0;j < m;j++) {
                    arr[i][j] = in.nextInt();
                    // 计算行列 0 的个数,为 0 时不算入乘积
                    if (arr[i][j] == 0) {
                        row0[i]++;
                        col0[j]++;
                    }else {
                        row[i]*= arr[i][j];
                        col[j]*= arr[i][j];
                    }
                }
            }

            int ans = 0; // 存储最大值
            for (int i = 0;i < n;i++) {
                for (int j = 0;j < m;j++) {
                    // 计算行列中参与计算的值是否存在 0
                    int flag = row0[i] + col0[j];
                    if (arr[i][j] == 0) flag -= 2;
                    // 存在 0 时则整个乘积为 0 ,因此只要比较不存在 0 时的值就好
                    if (flag == 0) {
                        // 虽然 arr[i][j] 不参与计算,但它可能作为 0 出现在被除数中,因此分开计算
                        if (arr[i][j] == 0) {
                            ans = Math.max(ans, row[i]*col[j]);
                        }else {
                            ans = Math.max(ans, (row[i]/arr[i][j])*(col[j]/arr[i][j]));
                        }
                    }
                }
            }

            // 输出结果
            System.out.println(ans);
        }
    }
}

最后


如果有所收获请点赞支持一下作者哦,您的点赞是我持续创作的动力!! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1821714.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【编译原理】LL(1)分析法:C/C++实现

&#x1f516;墨香寄清辞&#xff1a;空谷幽篁风动&#xff0c;梦中仙鹤月明。 辗转千秋豪情在&#xff0c;乘风翱翔志不移。 目录 1. 编译原理之LL(1)分析法概念 1.1 编译原理 1.2 LL(1)分析法 2. LL(1)分析法 2.1 实验目的 2.2 实验要求 2.3 实验内容 2.3.1 实验解决…

Stable Diffusion【光影文字】:绚丽光影,文字与城市夜景的光影之约

今天我们我们结合城市夜景背景来看一下光影文字的效果&#xff0c;我们先来看一下效果图。 一. 字融城市夜景制作光影文字方法 【第一步】&#xff1a;制作底图这里制作底图使用黑底白字。我们使用美图秀秀制作一个"小梁子"字的底图。 字体&#xff1a;默认字体 图…

LLM 中什么是Prompts?如何使用LangChain 快速实现Prompts 一

LLM 中什么是Prompts&#xff1f;如何使用LangChain 快速实现Prompts 一 Prompt是一种基于自然语言处理的交互方式&#xff0c;它通过机器对自然语言的解析&#xff0c;实现用户与机器之间的沟通。 Prompt主要实现方式是通过建立相应的语料库和语义解析模型&#xff0c;来将自…

对于毕业季拨穗礼上的奇怪举动与表情包,您怎么看?

对于毕业季拨穗礼上的奇怪举动与表情包&#xff0c;您怎么看&#xff1f; 拨穗代表稻穗或麦穗成熟。什么叫拨穗礼&#xff1f;就是把你头上学士帽的流苏从右边换到左边的动作。它象征着你已学有所成,可以展翅高飞了。 又到毕业季&#xff0c;各大高校的校园里弥漫着别离与期待…

评论员稿:逯伟军,年轻人为何为这样的“新中式”买单?

继老钱风、美拉德、Y2K等流行趋势之后&#xff0c;“新中式”毫无争议地荣登当下最为热门的穿搭趋势之列。 不管是出于对传统文化的热爱&#xff0c;还是仅仅被中式美学的设计所吸引&#xff0c;总之从明星到时尚博主&#xff0c;再到普通消费者&#xff0c;新中式风格在社交平…

Talk|新加坡国立大学贾鑫宇:适用于高自由度机器人的运动控制器

本期为TechBeat人工智能社区第600期线上Talk。 北京时间6月13日(周四)20:00&#xff0c;新加坡国立大学博士生—贾鑫宇的Talk已经准时在TechBeat人工智能社区开播&#xff01; 他与大家分享的主题是: “适用于高自由度机器人的运动控制器”&#xff0c;向大家系统地介绍了如何通…

期货到底难在哪里?

第一难&#xff1a;使用杠杠&#xff0c;杠杠放大的其实是你性格、天赋和技能上的弱点&#xff0c;同时相应缩小你这三个方面的优点&#xff1b;第二难&#xff1a;双向交易。如果只能做多&#xff0c;理论上你每次交易将有50%的概率盈利。现在既能做多又能做空&#xff0c;只剩…

最前端|还在焦虑网页内容无法保存?一文教你轻松给网页拍照

目录 一、需求背景 二、实现策略 三、基础实现 四、功能完善 五、效果演示 六、总结 一、需求背景 网页作为一种关键的信息传递媒介&#xff0c;承载着丰富多样的内容形态&#xff0c;包括但不限于文本、图像、表格及多媒体元素。然而&#xff0c;网页内容的动态性和不稳定…

郑州企业资信评价资质:工程咨询单位专业资信申报材料清单

在郑州企业申请工程咨询单位专业资信评价资质时&#xff0c;需要准备一系列详细的申报材料。以下是根据参考文章中的相关数字和信息&#xff0c;清晰、分点表示和归纳的工程咨询单位专业资信申报材料清单&#xff1a; 一、基础材料 企业法人营业执照&#xff1a;提供企业法人营…

微信小程序投票系统(包含微信小程序端)

&#x1f4f1;微信投票小程序&#xff1a;轻松发起&#xff0c;快速统计 一、引言 在数字化时代&#xff0c;微信作为我们日常生活中不可或缺的社交工具&#xff0c;不仅为我们提供了沟通交流的平台&#xff0c;还衍生出了许多实用的小程序。其中&#xff0c;微信投票小程序凭…

《现代通信原理与技术》--数字信号的最佳接收实验报告

《现代通信原理与技术》 数字信号的最佳接收实验报告 实 验&#xff1a;数字信号的最佳接收实验报告 目录 摘要......................................................................................................3 引言........................................…

嵌入式系统复习(一)

第一章 嵌入式系统的定义、特点 嵌入式系统是以应用为中心&#xff0c;以计算机技术为基础&#xff0c;软件硬件可裁剪&#xff0c;适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。 特点&#xff1a;嵌入性 专用性 计算机系统 嵌入式系统典型组成…

线代老师大PK,这四位胜出!

说实话&#xff0c;线代真的别乱跟老师 因为每个老师讲课适用的人群不一样&#xff0c;比如都说李永乐老师线代讲的好&#xff0c;但是我去听完发现&#xff0c;李永乐老师的线代讲的虽然好&#xff0c;但是对于零基础或者基础不好的考生来说&#xff0c;真的有点不友好&#…

Python开发者必备:Python多平台消息推送工具

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 文章内容 📒🚀 安装📝 使用方法📝 同步发送消息📝 异步发送消息📝 使用配置文件发送消息📝 示例配置文件⚓️ 相关链接 ⚓️📖 介绍 📖 你是否需要一个强大且灵活的工具来实现多平台消息推送?那么你一定不能…

手机直播不用麦克风可以吗?一文看懂无线麦克风哪个好

市面上对于无线麦克风的需求有增无减&#xff0c;原因是直播、短视频行业火爆&#xff0c;许多人都开始加入这一行业&#xff0c;不过对于麦克风这类产品的疑问也越来越多。例如&#xff1a;无线麦克风怎么选&#xff1f;实不实用&#xff1f;手机直播不用麦克风可以吗&#xf…

服务器数据恢复—EMC Isilon存储中被误删的虚拟机数据恢复案例

服务器存储数据恢复环境&#xff1a; EMC Isilon S200集群存储&#xff0c;共三个节点&#xff0c;每节点配置12块SATA硬盘。 服务器存储故障&#xff1a; 工作人员误操作删除虚拟机&#xff0c;虚拟机中数据包括数据库、MP4、AS、TS类型的视频文件等。需要恢复数据的虚拟机通…

雪球产品学习,大雪球vs小雪球

part1 大雪球 一、 雪球产品的要素 1.1 定义:固收+期权的结合 具备敲入,敲出的Barrier put (看跌=认沽) 期权的买方:产品发行方 期权的卖方:雪球产品购买者 1.2 七要素 挂钩标的,锁定期,敲入价格,敲出价格,产品期限,观察频率,产品报价 1.3 挂钩标的 个股or指…

AI类人工智能产品经理的丛林法则

AI是大家都很关注的领域&#xff0c;然而对于大部分想要入行的同学来讲&#xff0c;AI的算法技术门槛相对较高&#xff0c;让很多空有热血但是缺少数学背景的同学望而却步。不知道什么时候&#xff0c;可能是“人人都是产品经理”这个论调的影响&#xff0c;产品经理这个岗位逐…

剖析框架代码结构的系统方法(下)

当面对Dubbo、Spring Cloud、Mybatis等开源框架时,我们可以采用一定的系统性的方法来快速把握它们的代码结构。这些系统方法包括对架构演进过程、核心执行流程、基础架构组成和可扩展性设计等维度的讨论。 在上一讲中,我们已经讨论了架构演进过程和核心执行流程这两个系统方法…

【实践功能记录6】表格列悬浮展示tooltip信息

需求描述&#xff1a; 鼠标悬浮在表格的IP字段上时&#xff0c;使用tooltip展示IP信息&#xff0c;如图&#xff1a; 1.封装根据IP展示信息的组件 请求接口获取IP信息&#xff0c;注意请求接口时防抖 <!-- 根据IP展示资产信息 --> <template><div><el-…