【华为机试真题 JAVA】矩阵最大值-100

【编程题目 |100分】矩阵最大值【2022 Q2考试题】

时间限制:C/C++ 1秒,其他语言 2秒

空间限制:C/C++262144K,其他语言524288K

64bit IO Format:%lld

本题可使用本地IDE编码,不能使用本地已有代码,无跳出限制,

编码后请点击“保存并调试”按钮进行代码提交。

题目描述

给定一个仅包含0和1的N*N二维矩阵,请计算二维矩阵的最大值,计算规则如下:

每行元素按下标顺序组成一个二进制数(下标越大越排在低位),二进制数的值就是该行的值。矩阵各行值之和为矩阵的值。
允许通过向左或向右整体循环移动每行元素来改变各元素在行中的位置。 比如:
[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。

输入描述:

输入的第一行为正整数,记录了N的大小,0 < N <= 20。
输入的第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。
总和为24+24+20+28+26=122。

解题思路:

对于复杂问题的求解,我们要善于将复杂问题拆解为多个简单的小问题。

现在要求整个二维矩阵的最大值,而矩阵中每一行都是相对独立的,因此只要求解每一行的最大值,再逐个将每一行的结果累加起来即为最终的结果。

单行的最大值,通过字符串旋转后,由二机制转十进制后比较大小得到单行的最大值。

 String origin = Arrays.stream(matrix).collect(Collectors.joining(""));
// 右移动0位作为max的默认值
int max = Integer.parseInt(origin, 2);
// 循环移位,从右移1位,一直到len-1位
for (int i = 1; i <= matrix.length - 1; ++i) {
    String firstPart = origin.substring(0, matrix.length - i);
    String secondPart = origin.substring(matrix.length - i, matrix.length);
    String concatString = String.format("%s%s", secondPart, firstPart);
    int value = Integer.parseInt(concatString, 2);
    max = Math.max(max, value);
}

这里以1,0,0,0,1为例,展示移位0位到len-1位后的数值,分别与最大值进行比较,更新最大值。

在这里插入图片描述

示例代码

import java.util.Arrays;
import java.util.Scanner;
import java.util.stream.Collectors;


public class MaxMatrix {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        scanner.nextLine();
        int total = 0;
        while (n > 0) {
            String[] matrix = scanner.nextLine().split(",");
            total += dealRow(matrix);
            n--;
        }
        System.out.println(total);
    }

    /**
     * 获取单行的最大值
     *
     * @param matrix
     * @return
     */
    private static int dealRow(String[] matrix) {
        String origin = Arrays.stream(matrix).collect(Collectors.joining(""));
        int max = Integer.parseInt(origin, 2);
        for (int i = 1; i <= matrix.length - 1; ++i) {
            String firstPart = origin.substring(0, matrix.length - i);
            String secondPart = origin.substring(matrix.length - i, matrix.length);
            String concatString = String.format("%s%s", secondPart, firstPart);
            int value = Integer.parseInt(concatString, 2);
            max = Math.max(max, value);
        }
        return max;
    }
}

总结

  • 难度:Medium
  • 分值:100
  • 考点:字符串分隔,字符串拼接等。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GeekerLou

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值