华为OD机考算法题:矩阵最大值

news/2024/7/20 19:07:31 标签: 华为od, 算法, 矩阵, 数据结构, Java, Javascript

题目部分

题目矩阵最大值
难度
题目说明给定一个仅包含 0 和 1 的 N*N 二维矩阵,请计算二维矩阵的最大值,计算规则如下:
1. 每行元素按下标顺序组成一个二进制数(下标越大越排在低位),二进制数的值就是该行的值。矩阵各行值之和为矩阵的值。
2. 允许通过向左或向右整体循环移动每行元素来改变各元素在行中的位置。
比如: [1,0,1,1,1] 向右整体循环移动 2 位变为 [1,1,1,0,1],二进制数为 11101,值为 29。
[1,0,1,1,1] 向左整体循环移动 2 位变为 [1,1,1,1,0],二进制数为 11110,值为 30。
输入描述1. 输入的第一行为正整数,记录了 N 的大小,0 < N <= 20。
2. 输入的第 2 到 N+1 行为二维矩阵信息,行内元素边角逗号分隔。
输出描述矩阵各行之和的最大值。
补充说明
------------------------------------------------------
示例
示例1
输入5
1,0,0,0,1
0,0,0,1,1
0,1,0,1,0
1,0,0,1,1
1,0,1,0,1
输出122
说明第一行向右整体循环移动 1 位,得到本行的最大值 [1,1,0,0,0],二进制值为 11000,十进制值为 24。
第二行向右整体循环移动 2 位,得到本行的最大值 [1,1,0,0,0],二进制值为 11000,十进制值为 24。
第三行向左整体循环移动 1 位,得到本行的最大值 [1,0,1,0,0],二进制值为 10100,十进制值为 20。
第四行向右整体循环移动 2 位,得到本行的最大值 [1,1,1,0,0],二进制值为 11100,十进制值为 28。
第五行向右整体循环移动 1 位,得到本行的最大值 [1,1,0,1,0],二进制值为 11010,十进制值为 26。
因此,矩阵的最大值为 122。


解读与分析

题目解读

矩阵的每一行为一个二进制数字,通过左右移动,得到最大的二进制数。输出所有最大二进制数之和。

分析与思路

1. 解析输入矩阵的每一行,并转换成对应的 10 进制数字;
2. 每一行的二进制数字每向右移动一位,相当于把这个数字(第一步中解析的数字,设为 value) 除以 2(取整),设为 valuePart1;然后再把 value % 2 的值(设为 modValue),乘以 2^{N-1},设为 valuePart2,计算 valuePart1 与 valuePart2 之和即为向右移动一位之后的结果。
3. 在第 2 步获取的数字的基础上,继续右移。对于一个 N 位的二进制,向右移动 N 位之后就会回到初始值。因而,移动 (N -1) 次求出这 N 个数中的最大值即可。

4. 然后对每一行的最大值求和,并输出。

时间复杂度为 O(n^{2}),空间复杂度为 O(n)。


代码实现

Java代码

import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;

/**
 * 支持优先级的队列
 * 
 * @since 2023.10.26
 * @version 0.1
 * @author Frank
 *
 */
public class MatrixMaxValue {
    public static void main(String[] args) {
	Scanner sc = new Scanner(System.in);
	while (sc.hasNext()) {
	    String input = sc.nextLine();
	    int count = Integer.parseInt( input );
	    int maxValue = 0;
	    for( int i = 0; i < count; i ++ )
	    {
		input = sc.nextLine();
		maxValue += getMaxValueEachLine( count, input );
	    }
	    System.out.println( maxValue );
	}
    }
    
    private static int getMaxValueEachLine( int count, String input )
    {
	int sourceValue = parseStringValue( input );
	int maxValue = sourceValue;
	 int curValue = sourceValue;
	// 右移 n - 1 次,求最大值
	for( int i = 0; i < count - 1; i ++ )
	{	   
	    int partValue1 = curValue / 2;
	    int partValue2 = (int) Math.round ( ( curValue % 2 ) * Math.pow( 2 , count - 1) );  // 使用round避免误差,不会越界
	    curValue = partValue1 + partValue2;
	    if( curValue > maxValue )
	    {
		maxValue = curValue;
	    }
	}
	return maxValue;
    }

    private static int parseStringValue( String input )
    {
	int ret = 0;
	String[] binaryArr = input.split( "," );
	for( int i = 0; i < binaryArr.length; i ++ )
	{
	    ret *= 2;
	    ret += Integer.parseInt( binaryArr[i] );
	}
	
	return ret;
    }
}

在以上 Java 代码中,Math.pow() 函数返回的是浮点数,为了避免浮点数计算时出现误差(大概率应该不会出现误差),为了保证程序的正确性,最后使用了 Math.round() 函数。
Math.round() 返回 long 型数字,为了避免数据类型不匹配,使用强制数据类型转换。因为 N 的最大值是 20,最大值 2^{20} - 1,比 10^{6} 稍大,此时不会越界。

JavaScript代码

const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
void async function() {
    while (line = await readline()) {
        var count = parseInt( line );
        var maxValue = 0;
        for (var i = 0; i < count; i++) {
            line = await readline()
            maxValue += getMaxValueEachLine(count, line );
        }
        console.log(maxValue);
    }
}();

function getMaxValueEachLine(count, input) {
    var sourceValue = parseStringValue(input);
    var maxValue = sourceValue;
    var curValue = sourceValue;
    // 右移 n - 1 次,求最大值
    for (var i = 0; i < count - 1; i++) {
        var partValue1 = parseInt( curValue / 2 );
        var partValue2 = Math.round((curValue % 2) * Math.pow(2, count - 1)); // 使用round,避免误差,不会越界
        curValue = partValue1 + partValue2;
        if (curValue > maxValue) {
            maxValue = curValue;
        }
    }
    return maxValue;
}

function parseStringValue(input) {
    var ret = 0;
    var binaryArr = input.split(",");
    for (var i = 0; i < binaryArr.length; i++) {
        ret *= 2;
        ret += parseInt(binaryArr[i]);
    }

    return ret;
}

(完)


http://www.niftyadmin.cn/n/5126941.html

相关文章

华为机试题:HJ5 进制转换

目录 第一章、算法题1.1&#xff09;题目描述1.2&#xff09;解题思路与答案1.3&#xff09;派仔的解题思路与答案1.3&#xff09;牛客链接 友情提醒: 先看文章目录&#xff0c;大致了解文章知识点结构&#xff0c;点击文章目录可直接跳转到文章指定位置。 第一章、算法题 1.…

ubuntu server 安装失败

网络问题&#xff0c;默认的cn那个mirrors不行&#xff0c;得替换国内得 安装Ubuntu server时有一个选项是 Mirror address 可以设置为 https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ 即 清华大学开源软件镜像站 的ubuntu地址

AMEYA360:炬玄智能车规级RTC芯片JXR191T为车载BMS提供16年稳态输出

北京炬玄智能科技有限公司聚焦于集成电路时钟芯片研发及生产&#xff0c;以高精度、高稳定性、集成化芯片和系统设计为主要方向&#xff0c;以实时时钟芯片(RTC)及模组为切入点&#xff0c;逐步将产品拓展到以TCXO、OCXO为代表的高端晶振芯片领域&#xff0c;最终打通整个时钟产…

偏微分方程为什么要先先验估计再求解的存在性,先验估计有什么用?

见知乎 https://www.zhihu.com/question/43549959?utm_sourceqq&utm_mediumsocial&utm_oi1315073218793488384

【漏洞复现】广联达 Linkworks办公OA SQL注入

广联达OA介绍 广联达办公OA是一款综合办公自动化解决方案&#xff0c;旨在提高组织内部的工作效率和协作能力。它提供了一系列功能和工具&#xff0c;帮助企业管理和处理日常办公任务、流程和文档。 资产收集 fofa&#xff1a;fid”/yV4r5PdARKT4jaqLjJYqw”或者body”/Servi…

ChatGLM2-6B模型尝鲜

一、前言 ChatGLM2-6B 是开源中英双语对话模型 ChatGLM-6B 的第二代版本&#xff0c;在保留了初代模型对话流畅、部署门槛较低等众多优秀特性的基础之上&#xff0c;ChatGLM2-6B 引入了如下新特性&#xff1a; 更强大的性能&#xff1a;基于 ChatGLM 初代模型的开发经验&#…

基于LSTM encoder-decoder模型实现英文转中文的翻译机器

前言 神经网络机器翻译(NMT, neuro machine tranlation)是AIGC发展道路上的一个重要应用。正是对这个应用的研究&#xff0c;发展出了注意力机制&#xff0c;在此基础上产生了AIGC领域的霸主transformer。我们今天先把注意力机制这些东西放一边&#xff0c;介绍一个对机器翻译…

DeOldify 接口化改造 集成 Flask

类似的图片修复项目 GFPGAN 的改造见我另一篇文 https://blog.csdn.net/weixin_43074462/article/details/132497146 DeOldify 是一款开源软件&#xff0c;用于给黑白照片或视频上色&#xff0c;效果还不错。 安装部署教程请参考别的文章&#xff0c;本文基于你给项目跑通&…