简单的自动曝光

简单的自动曝光 一、题目描述一个图像有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说明四、解题思路1. 核心思想采用暴力遍历 贪心选择的策略暴力遍历k 的取值范围是 [-255, 255]因为像素值范围是 0-255k 超出该范围时所有像素加 k 后都会被截取到边界差值不会更优覆盖所有可能的有效调整贪心选择对每个 k 计算 “调整后平均值与 128 的绝对差值”始终保留差值最小的 k若差值相同选择更小的 k题目规则。2. 问题本质分析该问题是单变量优化问题核心特征优化变量整数 k调整量目标函数|(调整后像素平均值) - 128|需最小化该函数约束条件调整后的像素值必须截取到 [0,255]解的范围k∈[-255, 255]超出该范围无意义所有像素都会被截取到边界无法优化差值平局规则多个 k 的目标函数值相同时选更小的 k。3. 核心逻辑遍历所有有效 kk 从 - 255 到 255覆盖所有能改变像素调整结果的取值像素调整与求和对每个 k计算所有像素加 k 后截取到 [0,255] 的新值累加求和差值计算与最优选择计算调整后平均值与 128 的绝对差值若差值更小更新最优 k若差值相等选更小的 k。4. 步骤拆解输入处理读取像素值字符串转为整数数组初始化最优值bestK0初始最优 k、minDiff极大值初始最小差值遍历所有 k 值-255 到 255对每个 k遍历所有像素像素值加 k得到临时值将临时值截取到 [0,255] 范围Math.max(0, Math.min(temp, 255))累加所有截取后的像素值得到总和计算调整后像素的平均值转为 double 避免整数除法精度丢失计算平均值与 128 的绝对差值按规则更新最优 k差值更小或差值相等但 k 更小输出结果返回最优 k 值。五、代码实现import java.util.Scanner; public class OptimalKForPixel { public static void main(String[] args) { Scanner scanner new Scanner(System.in); // 1. 读取输入转为整数数组 String[] input scanner.nextLine().split( ); int n input.length; int[] img new int[n]; for (int i 0; i n; i) { img[i] Integer.parseInt(input[i]); } // 2. 寻找最优k值 int optimalK findOptimalK(img, n); // 3. 输出结果 System.out.println(optimalK); scanner.close(); } /** * 核心方法找到使新像素平均值最接近128的k值 * param img 原始像素数组 * param n 数组长度 * return 最优k值 */ private static int findOptimalK(int[] img, int n) { int bestK 0; double minDiff Double.MAX_VALUE; // 记录最小差值 // 遍历所有可能的k值范围[-255, 255]覆盖所有有效调整 for (int k -255; k 255; k) { int sum 0; // 计算每个像素加k后的截取值并求和 for (int pixel : img) { int temp pixel k; // 截取到[0,255]范围 int newVal Math.max(0, Math.min(temp, 255)); sum newVal; } // 计算平均值 double avg (double) sum / n; // 计算与128的绝对差值 double diff Math.abs(avg - 128); // 更新最优k差值更小或差值相等但k更小 if (diff minDiff || (diff minDiff k bestK)) { minDiff diff; bestK k; } } return bestK; } }