华为OD机试(C卷+D卷)2024真题目录(Java & c++ & python)
题目描述
从前有个村庄,村民们喜欢在各种田地上插上小旗子,旗子上标识了各种不同的数字。
某天集体村民决定将覆盖相同数字的最小矩阵形的土地分配给村里做出巨大贡献的村民,请问此次分配土地,做出贡献的村民种最大会分配多大面积?
输入描述
第一行输入 m 和 n,
m 代表村子的土地的长
n 代表土地的宽
第二行开始输入地图上的具体标识
输出描述
此次分配土地,做出贡献的村民种最大会分配多大面积
备注
旗子上的数字为1~500,土地边长不超过500未插旗子的土地用0标识
示例1
输入
3 3
1 0 1
0 0 0
0 1 0
输出
9
说明:土地上的旗子为1,其坐标分别为(0,0),(2,1)以及(0,2),为了覆盖所有旗子,矩阵需要覆盖的横坐标为0和2,纵坐标为0和2,所以面积为9,即(2-0+1)*(2-0+1)= 9
示例2
输入
3 3
1 0 2
0 0 0
0 3 4
输出
1
说明:由于不存在成对的小旗子,故而返回1,即一块土地的面积。
解题思路
本题解题思路很简单,只需要统计出相同数字的出现的所有坐标位置中:
- 最小的横坐标
- 最大的横坐标
- 最小的纵坐标
- 最大的纵坐标
那么包含所有相同数字的最小矩形面积为:
(最大的横坐标 - 最小的横坐标 + 1) * (最大的纵坐标 - 最小的纵坐标 + 1)
比如:
图示中数字1的所有坐标位置(1,1)、(1,3)、(2,4)、(3,1)、(3,3)中:
最小的横坐标:1
最大的横坐标:3
最小的纵坐标:1
最大的纵坐标:4
那么包含所有数字1的最小矩形面积为 12
参考代码
import java.util.*;
public class Main {
static class Rectangle {
int minRow = Integer.MAX_VALUE;
int maxRow = Integer.MIN_VALUE;
int minCol = Integer.MAX_VALUE;
int maxCol = Integer.MIN_VALUE;
private void updateRow(int row) {
this.minRow = Math.min(this.minRow, row);
this.maxRow = Math.max(this.maxRow, row);
}
private void updateCol(int col) {
this.minCol = Math.min(this.minCol, col);
this.maxCol = Math.max(this.maxCol, col);
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int rows = scanner.nextInt(); // 长(行数)
int cols = scanner.nextInt(); // 宽(列数)
HashMap<Integer, Rectangle> rectangles = new HashMap<>();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
int value = scanner.nextInt();
if (value > 0) {
rectangles.putIfAbsent(value, new Rectangle());
rectangles.get(value).updateRow(i);
rectangles.get(value).updateCol(j);
}
}
}
int maxArea = 0;
for (int key : rectangles.keySet()) {
Rectangle rectangle = rectangles.get(key);
maxArea = Math.max(maxArea, (rectangle.maxRow - rectangle.minRow + 1) * (rectangle.maxCol - rectangle.minCol + 1));
}
System.out.println(maxArea);
}
}