【华为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。

    像素值调整规则:

    每个像素值 arri 被调整为 newVal = Math.min(255, Math.max(0, arri + 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);
}

注意:

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

相关推荐
IT小白杨4 分钟前
从环境制备到自动化工作流:多账号运营的工程化架构拆解
java·经验分享·自动化·安全架构·指纹浏览器
长和信泰光伏储能15 分钟前
京津冀光伏发电:绿色能源的未来之路
python·能源
豆瓣鸡29 分钟前
算法日记 - Day3
java·开发语言·算法
浦信仿真大讲堂39 分钟前
从重复操作到自动化闭环:如何让 CST 与 Python 真正协同起来
python·自动化·cst·仿真软件·达索软件
萧瑟余晖44 分钟前
Java深入解析篇九之NIO详解
java·网络·nio
The Chosen One9851 小时前
高进度算法模板速记(待完善)
java·前端·算法
Gu Gu Study1 小时前
ScoutLoop开放域深度研究引擎(agent的初步设计想法)
人工智能·python
卷无止境2 小时前
写代码这件事,到底该讲究点什么?
后端·python
卷无止境2 小时前
循环复杂度到底在算什么,Python 代码怎么才能写得让人一看就懂
后端·python
lpfasd1232 小时前
MediaCrawler 项目深度分析
chrome·python·chrome devtools