【华为OD-E卷-简单的自动曝光 100分(python、java、c++、js、c)】

【华为OD-E卷-简单的自动曝光 100分(python、java、c++、js、c)】

题目

一个图像有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
用例二:
输入:
129 130 129 130
输出:
-2

python解法

  • 解题思路:
  • 目标:找到一个调整值 k,使得对图像像素值进行调整后,像素值的平均值尽量接近128(即接近中值区域)。
    像素值调整规则:
    每个像素值 p 在调整后需满足范围约束 [0, 255]。
    调整公式为:adjusted_img = [max(0, min(255, p + k)) for p in img]。
    搜索范围:
    k 在范围 [-127, 128] 内搜索。
    优化准则:
    优先使调整后的像素值平均值与128的绝对差值最小。
    如果差值相等,选择较小的 k。
    最终返回:
    最优调整值 k。
python 复制代码
def closest_to_median(img):
    # 初始化最优的调整值和最小差值
    best_k = None
    min_diff = float('inf')

    # 遍历可能的调整值k,范围是[-127, 128]
    for k in range(-127, 129):
        # 调整像素值,确保结果在[0, 255]范围内
        adjusted_img = [max(0, min(255, p + k)) for p in img]

        # 计算调整后的像素值的平均值
        avg_val = sum(adjusted_img) / len(img)

        # 计算平均值与目标128的绝对差值
        diff = abs(avg_val - 128)

        # 如果当前调整后的差值更小,或者在差值相等时k更小,则更新最优解
        if diff < min_diff or (diff == min_diff and (best_k is None or k < best_k)):
            min_diff = diff
            best_k = k

    # 返回最优调整值
    return best_k

# 读取像素值作为输入
pixels = list(map(int, input().split()))

# 输出计算出的最优调整值
print(closest_to_median(pixels))

java解法

  • 解题思路
  • 目标:找到一个调整值 k,使对像素值调整后,像素值的平均值尽可能接近128。
    调整规则:
    每个像素值 pixel 被调整为 newVal = max(0, min(255, pixel + k))。
    调整后需满足范围 [0, 255]。
    二分搜索:
    利用二分搜索的思想在 k ∈ [-127, 128] 范围内搜索。
    对每个中间值 mid,计算调整后的平均值 currentAvg。
    根据 currentAvg 与128的差异更新最优调整值 bestK。
    如果 currentAvg < 128,说明需要增大 k,否则需要减小 k。
    最终返回:
    找到的最优调整值 k。
java 复制代码
import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        // 读取输入的像素值,以空格分隔
        String str = sc.nextLine();
        int[] pixels = Arrays.stream(str.split(" ")).mapToInt(Integer::parseInt).toArray();

        // 输出最优的调整值 k
        System.out.println(findBestK(pixels));
    }

    // 找到使调整后平均值最接近128的最佳k值
    public static int findBestK(int[] pixels) {
        int left = -127, right = 128; // 搜索范围
        int bestK = 0;               // 记录当前最佳的k值
        double bestDiff = Double.MAX_VALUE; // 当前最小的与128的差异

        // 二分搜索
        while (left <= right) {
            int mid = (left + right) / 2; // 计算中间值k
            double currentAvg = calculateAvg(pixels, mid); // 计算调整后的平均值

            // 计算当前调整值与目标128的绝对差
            double diff = Math.abs(currentAvg - 128);

            // 更新最优k值,如果差值更小,或者在差值相等时k更小
            if (diff < bestDiff || (diff == bestDiff && mid < bestK)) {
                bestDiff = diff;
                bestK = mid;
            }

            // 根据调整后的平均值与128的大小关系调整搜索范围
            if (currentAvg < 128) {
                left = mid + 1; // 平均值小于128,增加k
            } else {
                right = mid - 1; // 平均值大于等于128,减小k
            }
        }

        return bestK; // 返回最佳k值
    }

    // 计算调整后的平均值
    public static double calculateAvg(int[] pixels, int k) {
        double sum = 0;

        // 遍历所有像素值,进行调整并计算总和
        for (int pixel : pixels) {
            int newVal = Math.max(0, Math.min(pixel + k, 255)); // 确保调整后的值在[0, 255]范围内
            sum += newVal;
        }

        // 返回调整后的平均值
        return sum / pixels.length;
    }
}

C++解法

  • 解题思路
cpp 复制代码
更新中

C解法

解题思路

c 复制代码
更新中

JS解法

解题思路

  • 目标: 找到一个调整值 k,使调整后的数组中所有像素值的平均值尽可能接近 128。

    像素值调整规则:

    每个像素值 arr[i] 被调整为 newVal = Math.min(255, Math.max(0, arr[i] + k)),确保调整后的像素值在 [0, 255] 范围内。

    搜索范围:

    使用二分搜索在 [-127, 128] 范围内寻找最优的调整值 k。

    优化准则:

    目标是让调整后数组的平均值与128的绝对差值最小。

    如果差值相等,选择较小的 k。

    二分搜索过程:

    计算当前中间值 mid 的调整后平均值与128的差异。

    根据与128的关系调整搜索范围。

    最终返回:

    找到的最优调整值 k。

javascript 复制代码
const readline = require("readline");

// 创建命令行接口,监听输入
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

// 监听每行输入
rl.on("line", (line) => {
  // 将输入的字符串转为整数数组
  const arr = line.split(" ").map(Number);

  // 调用函数计算最优调整值k并输出
  console.log(findOptimalK(arr));
});

// 主函数:找到最优的调整值k
function findOptimalK(arr) {
  let left = -127, right = 128; // 二分搜索范围
  let bestK = 0, bestDiff = Infinity; // 最优k值和当前最小差值

  // 二分搜索
  while (left <= right) {
    let mid = Math.floor((left + right) / 2); // 计算当前中间值
    const diffMid = calculateDiff(arr, mid); // 当前k对应的绝对差

    // 如果当前差值更小,更新最优k值;如果差值相等,选择较小的k
    if (diffMid < bestDiff) {
      bestDiff = diffMid;
      bestK = mid;
    } else if (diffMid === bestDiff) {
      bestK = Math.min(bestK, mid);
    }

    // 调整搜索范围,根据左右相邻差值大小进行移动
    if (calculateDiff(arr, mid - 1) < diffMid) {
      right = mid - 1;
    } else {
      left = mid + 1;
    }
  }

  return bestK; // 返回最优k值
}

// 辅助函数:计算调整后与128的绝对差
function calculateDiff(arr, k) {
  let sum = 0;

  // 遍历数组,对每个像素值进行调整
  for (let i = 0; i < arr.length; i++) {
    let newVal = arr[i] + k; // 调整像素值
    newVal = newVal < 0 ? 0 : newVal > 255 ? 255 : newVal; // 确保调整后的值在[0, 255]范围内
    sum += newVal; // 累加调整后的像素值
  }

  // 返回调整后平均值与128的绝对差
  return Math.abs(sum / arr.length - 128);
}

注意:

如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏

相关推荐
Oneforlove_twoforjob4 分钟前
【Java基础面试题033】Java泛型的作用是什么?
java·开发语言
engchina20 分钟前
如何在 Python 中忽略烦人的警告?
开发语言·人工智能·python
向宇it21 分钟前
【从零开始入门unity游戏开发之——C#篇24】C#面向对象继承——万物之父(object)、装箱和拆箱、sealed 密封类
java·开发语言·unity·c#·游戏引擎
小蜗牛慢慢爬行23 分钟前
Hibernate、JPA、Spring DATA JPA、Hibernate 代理和架构
java·架构·hibernate
Dream_Snowar1 小时前
速通Python 第四节——函数
开发语言·python·算法
西猫雷婶1 小时前
python学opencv|读取图像(十四)BGR图像和HSV图像通道拆分
开发语言·python·opencv
星河梦瑾1 小时前
SpringBoot相关漏洞学习资料
java·经验分享·spring boot·安全
黄名富1 小时前
Redis 附加功能(二)— 自动过期、流水线与事务及Lua脚本
java·数据库·redis·lua
love静思冥想1 小时前
JMeter 使用详解
java·jmeter
言、雲1 小时前
从tryLock()源码来出发,解析Redisson的重试机制和看门狗机制
java·开发语言·数据库