华为OD机试真题——简单的自动曝光平均像素(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现
2025 A卷 100分 题型
本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式;
并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析;
本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分享》
华为OD机试真题《简单的自动曝光平均像素》:
文章快捷目录
题目描述及说明
Java
python
JavaScript
C
GO
题目名称:简单的自动曝光平均像素
知识点:数组遍历、数学计算(均值优化)
时间限制:1秒
空间限制:256MB
限定语言:不限
题目描述
一个图像有n个像素点,存储在一个长度为n的数组img
里,每个像素点的取值范围为[0,255]
的正整数。请你给图像每个像素点值加上一个整数k
(可以是负数),得到新图newImg
,使得新图newImg
的所有像素平均值最接近中位值128
。请输出这个整数k
。
输入描述
输入为n个整数,中间用空格分开。
输出描述
输出一个整数k
。
备注
1 <= n <= 100
- 如有多个整数
k
满足条件,输出最小的那个k
。 - 新图的像素值会自动截取到
[0,255]
范围。当新像素值<0
时,其值会更改为0
;当新像素值>255
时,其值会更改为255
。
(例如:newImg="-1 -2 256"
会自动更改为"0 0 255"
)
示例
- 输入:
0 0 0 0
输出:128
解释:四个像素值均为0,增加128后平均值为128。 - 输入:
129 130 129 130
输出:-2
解释:k=-1
时均值为128.5,k=-2
时均值为127.5,输出较小的-2
。
Java
问题分析
题目要求在给定像素数组的基础上,找到一个整数k,使得每个像素值加上k后截断到[0,255]范围内的新像素平均值最接近128。若有多个k满足条件,选择最小的k。
解题思路
- 遍历所有可能的k值:由于像素值范围是[0,255],k的有效范围是[-255, 255]。
- 计算截断后的像素值:对每个k,计算每个像素加上k后的值,并截断到[0,255]。
- 求平均值并比较:计算截断后的像素平均值与128的绝对差,记录差值最小的k,若差值相同则取较小的k。
代码实现
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);String[] parts = scanner.nextLine().split(" ");int n = parts.length;int[] img = new int[n];for (int i = 0; i < n; i++) {img[i] = Integer.parseInt(parts[i]);}int bestK = -256; // 初始值设为无效的-256double minDiff = Double.MAX_VALUE;// 遍历k的可能范围[-255, 255]for (int k = -255; k <= 255; k++) {long sum = 0;for (int x : img) {int adjusted = x + k;adjusted = Math.max(0, Math.min(255, adjusted)); // 截断到[0,255]sum += adjusted;}double average = (double) sum / n;double diff = Math.abs(average - 128);// 更新最优解if (diff < minDiff || (diff == minDiff && k < bestK)) {minDiff = diff;bestK = k;}}System.out.println(bestK);}
}
代码详解
-
输入处理:
String[] parts = scanner.nextLine().split(" "); int[] img = new int[n]; for (int i = 0; i < n; i++) {img[i] = Integer.parseInt(parts[i]); }
- 将输入字符串分割并转换为整数数组
img
。
- 将输入字符串分割并转换为整数数组
-
遍历k的范围:
for (int k = -255; k <= 255; k++) {
- 遍历k从-255到255,覆盖所有可能的有效值。
-
计算截断后的像素和:
int adjusted = x + k; adjusted = Math.max(0, Math.min(255, adjusted)); sum += adjusted;
- 对每个像素x,计算x +k并截断到[0,255],累加总和。
-
求平均值与差值:
double average = (double) sum / n; double diff = Math.abs(average - 128);
- 计算平均值和与128的绝对差。
-
更新最优解:
if (diff < minDiff || (diff == minDiff && k < bestK)) {minDiff = diff;bestK = k; }
- 若当前差值更小,或差值相同但k更小,则更新最优解。
示例测试
-
输入1:
0 0 0 0
输出:
128
说明:k=128时,所有像素变为128,均值为128。
-
输入2:
129 130 129 130
输出:
-2
说明:k=-2时均值为127.5,k=-1时均值为128.5,选择较小的k=-2。
-
输入3:
255 255
输出:
-127
说明:k=-127时,像素值变为128,均值为128。
综合分析
-
时间复杂度:
- O(511n),其中n为像素数量。遍历511次k,每次遍历n个像素。
-
空间复杂度:
- O(n),存储像素数组。
-
正确性</