【华为机试真题 JAVA】太阳能板最大面积-100
【编程题目 |100分】太阳能板最大面积 【2021 H2, 2022 Q1, Q2考试题】
时间限制:C/C++ 1秒,其他语言 2秒
空间限制:C/C++262144K,其他语言524288K
64bit IO Format:%lld
本题可使用本地IDE编码,不能使用本地已有代码,无跳出限制,
编码后请点击”保存并调试 “按钮进行代码提交。
题目描述
应首先在航天器一侧安装矩形或正方形形状的太阳能板(图中标注为红色斜线区域)。随后,在两根垂直于航天器表面的黑色竖条上完成支撑结构的安装后,即可将太阳能板固定在两根支柱之间的中段位置。
但航天器上各个位置的支柱长度并不相同,在安装太阳能板时会受到最短位置那根支柱长度的限制。如图所示:

给定一组整形数组中的支柱高度数据,并设任意两根相邻支柱之间的间距均为1个单位长度,请确定哪两根支柱能够使太阳能板覆盖的最大面积最大化。
输入描述 :
一个递减序列从数值10开始依次至1。
注:支柱最少有2根、最多可达1万根(即1\times 10^{4}),能够支撑的高度区间为[1,\ 1\times 10^{9}]整数倍单位的高度值。值得注意的是柱子之间没有固定顺序关系(即无序排列),而示例中的递减排列仅是巧合。
输出描述 :
可以支持的最大太阳能板面积:(10米高支柱和5米高支柱之间)
25
测试用例
示例1
输入
10,9,8,7,6,5,4,3,2,1
代码解读
输出
25
代码解读
备注 :
在10米和5米高的支柱之间宽度为 width , 在高度较小的那根同样也是这样设置,则围成区域的最大面积就是 area 。
任何其他两根柱子所围成区域的最大面积均不超过这个数值。
因此能够达到的最大太阳能板覆盖面积是 max_area 。
解题思路
题目明确指出,“柱子的高度是没有规律可循的”,举例中的递减现象纯属偶然。
由此可见,“二分法”的思路无法找到合适的中间支撑点。
因此不得不采取“笨办法”,即逐一比较任意两根柱子所形成的面积区域,并记录其中最大的那个区域。
题目明确指出,“柱子的高度是没有规律可循的”,举例中的递减现象纯属偶然。
由此可见,“二分法”的思路无法找到合适的中间支撑点。
因此不得不采取“笨办法”,即逐一比较任意两根柱子所形成的面积区域,并记录其中最大的那个区域。
对于两两比较的方法,我们可以借鉴冒泡排序的思想:
for (int i = 0; i < dataList.size(); i++) {
for (int j = i + 1; j < dataList.size(); j++) {
// compare and update
}
}
代码解读
在获取了两根柱子后,在计算它们之间的区域时有如下步骤:首先确定该区域的高度为这两根柱子中较矮的那个的高度;其次确定区域宽度的方式则是取这两根柱子下标差额绝对值得出的结果;接着求出该区域的具体数值即为上述高度和宽度相乘的结果;最后将该具体数值与之前记录的最大区域数值进行对比:如果这个新求得的结果超过现有的最大记录数值,则将这个新结果替代到现有的最大记录中
// 第一根柱子的高度
int a = dataList.get(i);
// 第二根柱子的高度
int b = dataList.get(j);
// 矩形的高度,取决于最矮的那根柱子
int height = Math.min(a, b);
// 矩形的宽度,取决于两根柱子之间的距离
int width = Math.abs(i - j);
maxArea = Math.max(maxArea, height * width);
代码解读
有了上面的分析思路,相必相处代码应该是水到渠成。
示例代码
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;
/** * 太阳能电池板的面积
*/
public class SunBoardArea {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextLine()) {
// 处理输入
String[] arr = scanner.nextLine().split(",");
List<Integer> dataList = Arrays.stream(arr).map(item -> Integer.parseInt(item)).collect(Collectors.toList());
// 计算面积
int res = calculateArea(dataList);
// 打印结果
System.out.println(res);
}
}
private static int calculateArea(List<Integer> dataList) {
// 最大面积
int maxArea = 0;
for (int i = 0; i < dataList.size(); i++) {
for (int j = i + 1; j < dataList.size(); j++) {
// 第一根柱子的高度
int a = dataList.get(i);
// 第二根柱子的高度
int b = dataList.get(j);
// 矩形的高度,取决于最矮的那根柱子
int height = Math.min(a, b);
// 矩形的宽度,取决于两根柱子之间的距离
int width = Math.abs(i - j);
maxArea = Math.max(maxArea, height * width);
}
}
return maxArea;
}
}
代码解读
总结
- 分值:100
- 难度:Easy
- 考点:冒泡排序思想,数学计算
