华为OD机试真题---简单的自动曝光

时间:2024-10-16 07:17:52

一、题目描述

一个图像有n个像素点,存储在一个长度为n的数组img里,每个像素点的取值范围是[0,255]的正整数。要求找到一个整数k,使得给图像每个像素点值加上k后,新图像newimg的所有像素平均值最接近中位值128。输出这个整数k。

二、解题思路

  1. 读取输入

    • 输入是一个整数数组,表示图像的像素值。
    • 数组的每个元素都是0到255之间的整数。
  2. 初始化变量

    • num:表示像素点的数量,即数组的长度。
    • diff:用于记录当前差值(平均值与128的差的绝对值)的最小值,初始化为一个足够大的数(如Integer.MAX_VALUE)。
    • ret:用于记录使差值最小的整数k,初始化为null或某个不可能的值。
  3. 遍历k的取值范围

    • 由于像素值范围是0到255,加上k后,新的像素值也应在这个范围内。
    • 因此,k的取值范围应确保新像素值不会超出这个范围。
    • 考虑到k可以是负数,且为了限制计算量,k的取值范围可以设定为[-127, 128]。这个范围的选择是基于:
      • 最小值-127确保加上最小的像素值0后不会变成负数。
      • 最大值128确保加上最大的像素值255后不会超过255。
  4. 计算新图像像素值

    • 对于每个像素值,将其加上k。
    • 使用Math.max(0, Math.min(255, pixel + k))确保新像素值在[0, 255]范围内。
  5. 更新差值

    • 计算新图像像素值的总和,并求出平均值。
    • 计算该平均值与128的差值(取绝对值)。
    • 如果当前差值比之前的差值小,则更新差值diff和对应的k值ret
  6. 输出结果

    • 遍历结束后,输出使差值最小的k值。

三、代码实现(Java示例)

以下是一个Java实现的示例代码:


import java.util.Arrays;

public class ImageAdjuster {

    /**
     * 找到一个整数k,使得给定图像每个像素点值加上k后,新图像的像素平均值最接近128。
     *
     * @param img 原始图像的像素数组,每个像素值范围在[0, 255]
     * @return 整数k,使得调整后的图像平均值最接近128
     */
    public static Integer adjustImage(int[] img) {
        // 初始化变量
        int num = img.length; // 图像像素点数量
        int diff = Integer.MAX_VALUE; // 初始差值设为最大值
        Integer ret = null; // 最终返回的结果k,默认为null

        // 遍历所有可能的k值
        for (int k = -127; k <= 128; k++) {
            // 计算新图像像素值
            int sum = 0;
            for (int pixel : img) {
                int newPixel = Math.max(0, Math.min(255, pixel + k));
                sum += newPixel;
            }

            // 计算新图像的平均值并更新差值
            int avg = sum / num;
            int currentDiff = Math.abs(avg - 128);
            if (currentDiff < diff) {
                diff = currentDiff;
                ret = k;
            }
        }

        return ret; // 输出结果
    }

    public static void main(String[] args) {
        int[] img = {50, 100, 150, 200}; // 示例输入
        System.out.println("调整图像所需的k值为:" + adjustImage(img));
    }
}

四、代码实现细节
  • 数组遍历:使用for循环遍历数组中的每个像素值。
  • 条件判断:使用Math.maxMath.min函数确保新像素值在有效范围内。
  • 数学运算:计算总和、平均值和差值。
  • 边界条件处理:确保k的取值范围不会导致新像素值超出0到255的范围。
五、示例与测试
  • 示例输入{50, 100, 150, 200}
  • 示例输出:根据示例输入和算法逻辑,计算出的k值应使新图像的像素平均值最接近128。
  • 测试
    • 多种输入情况,包括全0、全255、均匀分布、随机分布等。
    • 边界情况,如最小像素值、最大像素值、平均值接近128等。

六、注意事项

  1. 输入格式:确保输入是有效的整数数组,且每个元素在0到255之间。
  2. 输出格式:输出一个整数,表示使新图像像素平均值最接近128的k值。
  3. 性能优化:虽然本题的数据规模较小,但考虑到实际应用中图像可能非常大,可以考虑优化算法以提高效率。例如,使用更高效的遍历方法或并行计算。
  4. 边界条件:特别注意处理k的取值范围以及新像素值的范围限制,确保算法的正确性和鲁棒性。