【华为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);
}

注意:

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

相关推荐
customer0839 分钟前
【开源免费】基于SpringBoot+Vue.JS体育馆管理系统(JAVA毕业设计)
java·vue.js·spring boot·后端·开源
Miketutu1 小时前
Spring MVC消息转换器
java·spring
乔冠宇1 小时前
Java手写简单Merkle树
java·区块链·merkle树
小王子10242 小时前
设计模式Python版 组合模式
python·设计模式·组合模式
LUCIAZZZ2 小时前
简单的SQL语句的快速复习
java·数据库·sql
komo莫莫da3 小时前
寒假刷题Day19
java·开发语言
Mason Lin3 小时前
2025年1月22日(网络编程 udp)
网络·python·udp
清弦墨客3 小时前
【蓝桥杯】43697.机器人塔
python·蓝桥杯·程序算法
S-X-S4 小时前
算法总结-数组/字符串
java·数据结构·算法
linwq84 小时前
设计模式学习(二)
java·学习·设计模式