【华为OD-E卷 - 太阳能板最大面积 100分(python、java、c++、js、c)】
题目
给航天器一侧加装长方形或正方形的太阳能板(图中的红色斜线区域),需要先安装两个支柱(图中的黑色竖条),再在支柱的中间部分固定太阳能板。
但航天器不同位置的支柱长度不同,太阳能板的安装面积受限于最短一侧的那根支柱长度。如图:
现提供一组整形数组的支柱高度数据,假设每根支柱间距离相等为1个单位长度,计算如何选择两根支柱可以使太阳能板的面积最大
输入描述
- 10,9,8,7,6,5,4,3,2,1
注:支柱至少有2根,最多10000根,能支持的高度范围1~10^9的整数。柱子的高度是无序的,例子中递减只是巧合
输出描述
- 可以支持的最大太阳能板面积:(10米高支柱和5米高支柱之间)
用例
用例一:
输入:
10,9,8,7,6,5,4,3,2,1
- 1
输出:
25
- 1
python解法
- 解题思路:
- 这段代码实现了一个双指针算法,用于解决经典的“盛最多水的容器”问题。问题描述为:给定一个数组 heights,每个元素代表一个垂直线的高度,线的宽度固定为 1,找出能够容纳最多水的两个线段之间的区域面积。
初始化双指针:
左指针 start 指向数组的起始位置。
右指针 end 指向数组的末尾位置。
计算面积:
面积公式:(end - start) * min(heights[start], heights[end]),其中 (end - start) 是底边宽度,min(heights[start], heights[end]) 是高度。
更新最大面积:
每次计算出当前的面积后,与当前记录的最大面积进行比较,并更新最大值。
移动指针:
如果左边的高度小于或等于右边高度,移动左指针 start += 1,尝试寻找更高的左边界。
否则,移动右指针 end -= 1,尝试寻找更高的右边界。
终止条件:
当 start 和 end 相遇时,搜索结束
def find_max_container():
# 初始化双指针
start = 0
end = len(heights) - 1
largest_area = 0 # 用于记录最大的容器面积
while start < end: # 当左指针小于右指针时继续搜索
# 当前区域的面积
area = (end - start) * min(heights[start], heights[end])
# 更新最大面积
largest_area = max(largest_area, area)
# 根据高度大小移动指针,尝试找到更优解
if heights[start] <= heights[end]:
start += 1 # 左边界高度较小,移动左指针
else:
end -= 1 # 右边界高度较小,移动右指针
return largest_area # 返回最大面积
# 输入高度数组,以逗号分隔的形式
heights = list(map(int, input().split(",")))
# 输出最大容器面积
print(find_max_container())
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
java解法
- 解题思路
- 该代码使用双指针法解决了“盛最多水的容器”问题。问题的目标是找到一个数组中两条垂直线之间能够容纳的最大水量。
输入处理:
通过控制台读取逗号分隔的整数字符串,将其解析成整数数组 heights。
双指针法:
左指针 left 从数组起始位置开始,右指针 right 从数组末尾开始。
计算两个指针之间形成的容器面积,面积公式为:
area
(right - left)
×
min
(
heights[left]
,
heights[right]
)
area=(right - left)×min(heights[left],heights[right])
更新记录的最大面积 maxArea。
指针移动规则:
每次比较 heights[left] 和 heights[right]:
如果左边较矮,则移动左指针。
如果右边较矮,则移动右指针。
目的是尝试找到更大的高度,进而可能获得更大的面积。
终止条件:
当左指针和右指针相遇时,搜索结束
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// 创建一个扫描器对象用于读取输入
Scanner input = new Scanner(System.in);
// 读取输入的逗号分隔的高度字符串并拆分
String[] heightsStr = input.nextLine().split(",");
int[] heights = new int[heightsStr.length];
// 将字符串数组转换为整数数组
for (int i = 0; i < heightsStr.length; i++) {
heights[i] = Integer.parseInt(heightsStr[i]);
}
// 调用 findMaxArea 方法计算最大容器面积并输出结果
System.out.println(findMaxArea(heights));
}
/**
* 计算最大容器面积的函数
* @param heights 整数数组,表示垂直线的高度
* @return 最大容器面积
*/
public static long findMaxArea(int[] heights) {
// 初始化左右指针
int left = 0;
int right = heights.length - 1;
// 用于记录最大面积
long maxArea = 0;
// 当左指针小于右指针时继续搜索
while (left < right) {
// 计算当前容器的宽度
long width = right - left;
// 计算当前容器的高度(取两条线中较小的那条)
long height = Math.min(heights[left], heights[right]);
// 计算当前容器的面积
long area = width * height;
// 更新最大面积
maxArea = Math.max(maxArea, area);
// 移动较矮的指针,以尝试找到更高的边界
if (heights[left] < heights[right]) {
left++;
} else {
right--;
}
}
// 返回计算出的最大容器面积
return maxArea;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
C++解法
- 解题思路
更新中
- 1
C解法
更新中
- 1
JS解法
输入处理:
使用 readline 模块读取标准输入。
验证输入是否符合要求:
输入字符串必须包含逗号。
每个逗号分隔的元素必须是一个有效整数。
数组长度必须大于等于 2。
如果输入无效,则输出 1 表示错误。
双指针法:
左指针 left 从数组的起始位置开始。
右指针 right 从数组的末尾位置开始。
在指针未相遇前,计算当前指针形成的容器面积,更新最大面积 maxArea。
指针移动规则:
比较左右指针对应的高度:
如果左指针高度较小,则左指针右移。
如果右指针高度较小,则右指针左移。
目的是尽可能找到更高的线条,提高面积。
输出结果:
循环结束后,返回最大面积。
const readline = require("readline");
// 创建 readline 接口,用于读取标准输入
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
// 监听用户输入行
rl.on("line", (line) => {
try {
// 检查输入是否为空或者不包含逗号
if (!line || !line.includes(",")) {
throw new Error(); // 输入无效,抛出错误
}
// 将输入的字符串拆分为数组,并尝试解析为整数
const arr = line.split(",").map((ele) => {
const num = parseInt(ele, 10); // 将字符串转换为整数
if (isNaN(num)) {
throw new Error(); // 如果转换失败,抛出错误
}
return num; // 返回解析后的整数
});
// 检查数组长度是否小于 2
if (arr.length < 2) {
throw new Error(); // 输入数组长度不合法,抛出错误
}
// 输出计算得到的最大容器面积
console.log(findMaxArea(arr));
} catch (err) {
// 捕获错误并输出 "1" 表示输入错误
console.error("1");
}
});
/**
* 使用双指针法计算最大容器面积
* @param {number[]} arr 整数数组,表示垂直线的高度
* @return {number} 最大容器面积
*/
function findMaxArea(arr) {
let left = 0; // 左指针
let right = arr.length - 1; // 右指针
let maxArea = 0; // 初始化最大面积为 0
// 双指针法查找最大面积
while (left < right) {
let width = right - left; // 容器的宽度
let height = Math.min(arr[left], arr[right]); // 容器的高度(取两条线中较短的那条)
maxArea = Math.max(maxArea, width * height); // 更新最大面积
// 移动指针的规则:总是移动较矮的指针,尝试寻找更大的高度
if (arr[left] < arr[right]) {
left++; // 左边较矮,移动左指针
} else {
right--; // 右边较矮,移动右指针
}
}
return maxArea; // 返回最大面积
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
注意:
如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏
评论记录:
回复评论: