华为OD机试 - 分配土地 - 矩阵(Java 2024 D卷 100分)

在这里插入图片描述

华为OD机试 2024D卷题库疯狂收录中,刷题点这里

专栏导读

本专栏收录于《华为OD机试(JAVA)真题(D卷+C卷+A卷+B卷)》

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

一、题目描述

从前有个村庄,村民们喜欢在各种田地上插上小旗子,旗子上标识了各种不同的数字。某天集体村民决定将覆盖相同数字的最小矩阵形的土地的分配给为村里做出巨大贡献的村民,请问,此次分配土地,做出贡献的村民中最大会分配多大面积?

二、输入描述

第一行输入m和n,m代表村子的土地的长,n代表土地的宽

第二行开始输入地图上的具体标识

三、输出描述

输出需要分配的土地面积,即包含相同数字旗子的最小矩阵中的最大面积。

补充说明:

旗子上的数字为1-500,土地边长不超过500

未插旗子的土地用0标识

四、测试用例

测试用例1:

1、输入

3 3
1 0 1
0 0 0
0 1 0

2、输出

9

3、说明

土地上的旗子为1,其坐标分别为(0,0),(2,1)以及(0,2),为了覆盖所有旗子,矩阵需要覆盖的横坐标为0和2,纵坐标为0和2,所以面积为9,即(2-0+1)*(2-0+1)=9。

测试用例2:

1、输入

3 3
1 0 2
0 0 0
0 3 4

2、输出

1

3、说明

由于不存在成对的小旗子,故而返回1,即一块土地的面积。

五、解题思路

本题的目标是找到覆盖相同数字的最小矩形区域,并计算其中的最大面积。

我们有一个二维数组,代表村庄的土地,每个格子上插有一个数字旗子或者没有插旗子(用0表示)。

我们需要找到覆盖相同数字旗子的最小矩形区域,计算其中的最大面积。

  1. 定义一个矩形类 Rect 来记录每个数字的最小行、最大行、最小列和最大列。
  2. 该类提供方法更新行和列的最小最大值。
  3. 使用一个哈希映射 HashMap<Integer, Rect> 来记录每个数字及其对应的矩形区域边界。键为数字,值为 Rect 对象。
  4. 遍历输入的土地标识矩阵,对于每个非零数字,更新其在哈希映射中的矩形区域边界。
  5. 具体来说,对于每个非零数字,更新其最小行、最大行、最小列和最大列。
  6. 遍历哈希映射中的所有矩形区域,计算每个区域的面积,并找出其中的最大值。

六、Java算法源码

public class OdTest02 {
    static class Rect {
        int minRow = Integer.MAX_VALUE;
        int maxRow = Integer.MIN_VALUE;
        int minCol = Integer.MAX_VALUE;
        int maxCol = Integer.MIN_VALUE;

        // 设置行位置
        private void setRow(int row) {
            this.minRow = Math.min(this.minRow, row);
            this.maxRow = Math.max(this.maxRow, row);
        }

        // 设置列位置
        private void setCol(int col) {
            this.minCol = Math.min(this.minCol, col);
            this.maxCol = Math.max(this.maxCol, col);
        }
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int m = sc.nextInt(); // 读取土地的长(行数)
        int n = sc.nextInt(); // 读取土地的宽(列数)

        HashMap<Integer, Rect> rects = new HashMap<>(); // 用于记录每个数字对应的矩形区域
        for (int i = 0; i < m; i++) { // 遍历每一行
            for (int j = 0; j < n; j++) { // 遍历每一列
                int num = sc.nextInt(); // 读取当前格子的数字

                if (num > 0) { // 只处理大于0的数字
                    rects.putIfAbsent(num, new Rect()); // 如果数字首次出现,初始化一个新的矩形区域
                    rects.get(num).setRow(i); // 更新数字对应矩形的行位置
                    rects.get(num).setCol(j); // 更新数字对应矩形的列位置
                }
            }
        }

        int maxArea = 0; // 初始化最大面积为0
        for (int num : rects.keySet()) { // 遍历每个数字对应的矩形区域
            Rect rect = rects.get(num); // 获取矩形区域

            // 计算矩形的面积,并更新最大面积
            maxArea = Math.max(maxArea, (rect.maxRow - rect.minRow + 1) * (rect.maxCol - rect.minCol + 1));
        }

        System.out.println(maxArea); // 输出最大面积
    }
}

七、效果展示

1、输入

5 5
1 1 2 2 3
1 1 2 2 3
3 3 3 3 3
4 4 4 4 4
5 5 5 5 5

2、输出

15

3、说明

遍历矩阵,每个数字(大于0)记录其出现的最小和最大行列位置。

例如,数字 1 的最小矩形区域的边界是从 (0,0) 到 (1,1),因此面积为 (1-0+1) * (1-0+1) = 4。

数字 2 的最小矩形区域的边界是从 (0,2) 到 (1,3),因此面积为 (1-0+1) * (3-2+1) = 4。
数字 3 的最小矩形区域的边界是从 (2,0) 到 (2,4),以及 (0,4) 到 (2,4),最终面积为 (2-0+1) * (4-0+1) = 15。
数字 4 的最小矩形区域的边界是从 (3,0) 到 (3,4),最终面积为 (4-3+1) * (4-0+1) = 5。
数字 5 的最小矩形区域的边界是从 (4,0) 到 (4,4),最终面积为 (5-4+1) * (4-0+1) = 5。

在这里插入图片描述


🏆下一篇:华为OD机试 - 简易内存池 - 逻辑分析(Java 2024 D卷 200分)

🏆本文收录于,华为OD机试(JAVA)真题(D卷+C卷+A卷+B卷)

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。
在这里插入图片描述

  • 11
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
矩阵稀疏扫描是指对于一个二维矩阵,按照行优先的顺序扫描矩阵中的元素,并将非零元素按照行优先的顺序存储到一个一维数组中。 以下是一个使用Java语言实现的矩阵稀疏扫描的示例代码: ```java public class MatrixSparseScan { public static int[] sparseScan(int[][] matrix) { int row = matrix.length; // 矩阵的行数 int col = matrix[0].length; // 矩阵的列数 // 计算非零元素的个数 int count = 0; for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { if (matrix[i][j] != 0) { count++; } } } // 创建稀疏数组 int[] sparseArray = new int[count * 3 + 1]; sparseArray[0] = row; // 存储矩阵的行数 sparseArray[1] = col; // 存储矩阵的列数 sparseArray[2] = count; // 存储非零元素的个数 int index = 3; // 稀疏数组的索引 for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { if (matrix[i][j] != 0) { sparseArray[index++] = i; // 存储非零元素的行索引 sparseArray[index++] = j; // 存储非零元素的列索引 sparseArray[index++] = matrix[i][j]; // 存储非零元素的值 } } } return sparseArray; } public static void main(String[] args) { int[][] matrix = { {1, 0, 0}, {0, 2, 0}, {0, 0, 3} }; int[] sparseArray = sparseScan(matrix); for (int i = 0; i < sparseArray.length; i++) { System.out.print(sparseArray[i] + " "); } } } ``` 运行上述代码,输出结果为:3 3 3 0 0 1 1 1 2 2 2 3。其中,3表示矩阵的行数,3表示矩阵的列数,3表示非零元素的个数,接下来依次为非零元素的行索引、列索引和值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

哪 吒

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

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

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

打赏作者

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

抵扣说明:

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

余额充值