华为OD机考算法题:简单的自动曝光

news/2024/7/20 16:57:18 标签: 华为od, 算法, Java, JavaScript, 数据结构

题目部分

题目简单的自动曝光
难度
题目说明一个图像有 n 个像素点,存储在一个长度为n的数组img里,每个像素点的取值范围 [0,255] 的正整数。
请你给图像每个像素点值加上一个整数k(可以是负数),得到新图newlmg,使得新图newImg的所有像素平均值最接近中位值128。
请输出这个整数k。
输入描述n个整数,中间用空格分开。
例如:
0 0 0 0
4个数值,中间用空格分开。
输出描述一个整数 k 。
补充说明1<=n<=100;
如有多个整数k都满足,输出小的那个k;
新图的像素值会自动截取到[0,255]范围。当新像素值<0,其值会更改为0:当新像 素值>255,其值会更改为255;
例如newlmg="-1 -2 256",会自动更改为"0 0 255"。
------------------------------------------------------
示例
示例1
输入0 0 0 0
输出128
说明四个像素值都为0。
示例2
输入129 130 129 130
输出-2
说明-1 的均值是 128.5,-2 的均值是 127.5,输出较小的数 -2。


解读与分析

题目解读

题目题目给出一系列初始整数值,取值范围 [ 0, 255 ]。要求给一个整数 k (可以为负数),与这一系列整数数相加(需要注意的是:当相加的结果小于或等于 0 时,取值为 0;当相加结果大于 255 时,取值为 255),使这一系列数字的平均值接近 128。

如果存在多个整数满足条件,则输出较小的那个值。

分析与思路

此题中,这一系列整数的个数不超过 100。

思路非常简单,直接把 k 的值设为 -255 开始, 逐个与整数相加,小于 0 则取 0,大于 255 则取 255,求和之后,求平均值,计算平均值与 128 差值的绝对值。
然后 k 加 1(为 -254),继续进行上面的操作求平均值,直至 k 的最大值 255 求完平均值。最后,首次出现的绝对值,即为所求的 k。 

在这个思路中,有 2 点可以优化:
1. k 的取值范围。刚才的思路中,k 的取值范围是[ -255, 255 ]。最终要求所有数字的平均值接近 128。我们思考一下,原始数字最大和最小的边界条件。显然,当 n 个数全为 255 时,平均值最大,此时 k 为 -127,即可保证所有数字平均值为128;当 n 个数全为 0 ,它们平均值最小,此时 k 为 128,即可保证所有数字平均值为 128 。显然,k 的取值范围可以缩小为 [ -127, 128 ]。
2. 平均值计算。在上面算法中,我们把所有数字求和,接着除以 n 求平均值,然后计算与 128 差值的绝对值。在除以 n 的时候,可能存在小数。而小数的计算可能存在误差,造成数字不准确的额情况。为了避免误差,我们可以在求和(假设和为 sum)之后,计算 | sum - 128 * n | ,保证它为最小值。稍加说明,n 的最大值为 100,使用 int 整形可满足取值范围。

上面的算法在[ -127, 128 ]范围内,让 k 逐次和 n 个数做加法。在最坏的情况下,共需要计算 256 * n 次。


代码实现

Java代码

import java.util.Scanner;

/**
 * 简单的自动曝光
 * @since 2023.09.09
 * @version 0.1
 * @author Frank
 *
 */
public class ImgPixelChange {
	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);
		while (sc.hasNext()) {
			String input = sc.nextLine();
			String[] strNumbers = input.split( " " );
			int[] numbers = convertStrNumbers2Int( strNumbers);
			processImgPixelChange( numbers );
		}
	}
	
	private static int[] convertStrNumbers2Int( String[] numbers)
	{
		int[] ret = new int[numbers.length];
		for( int i = 0; i < numbers.length; i ++ )
		{
			ret[i] = Integer.parseInt( numbers[i] );
		}
		return ret;
	}
	
	private static void processImgPixelChange( int numbers[] )
	{
		int minDiff = Integer.MAX_VALUE;
		int AVERAGE_VALUE = 128 * numbers.length;
		int finalK = -127;
		for( int k = -127; k <= 128; k ++ )
		{
			int sum = 0;
			for( int i = 0; i < numbers.length; i ++ )
			{
				int tmpNumber = numbers[i] + k;
				if( tmpNumber < 0 )
				{
					tmpNumber = 0;
				}else if( tmpNumber > 255 )
				{
					tmpNumber = 255;
				}
				sum += tmpNumber;
			}
			int diff = Math.abs( sum - AVERAGE_VALUE );
			if( diff < minDiff )
			{
				minDiff = diff;
				finalK = k;
			}
		}		
		
		System.out.println( finalK );
	}
}

JavaScript代码

const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
void async function() {
    while (line = await readline()) {
        var strNumbers = line.split(" ");
        var numbers = convertStrNumbers2Int(strNumbers);
        processImgPixelChange(numbers);
    }
}();

function convertStrNumbers2Int( numbers) {
    var ret = new Array(numbers.length );
    for ( var i = 0; i < numbers.length; i++) {
        ret[i] = parseInt(numbers[i]);
    }
    return ret;
}

function processImgPixelChange(numbers) {
    var minDiff = Number.MAX_VALUE;
    var AVERAGE_VALUE = 128 * numbers.length;
    var finalK = -127;
    for (var k = -127; k <= 128; k++) {
        var sum = 0;
        for (var i = 0; i < numbers.length; i++) {
            var tmpNumber = numbers[i] + k;
            if (tmpNumber < 0) {
                tmpNumber = 0;
            } else if (tmpNumber > 255) {
                tmpNumber = 255;
            }
            sum += tmpNumber;
        }
        var diff = Math.abs(sum - AVERAGE_VALUE);
        if (diff < minDiff) {
            minDiff = diff;
            finalK = k;
        }
    }
    console.log(finalK);
}

(完)


http://www.niftyadmin.cn/n/5017246.html

相关文章

Spring Boot 中使用 Poi-tl 渲染数据并生成 Word 文档

本文 Demo 已收录到 demo-for-all-in-java 项目中&#xff0c;欢迎大家 star 支持&#xff01;后续将持续更新&#xff01; 前言 产品经理急冲冲地走了过来。「现在需要将按这些数据生成一个 Word 报告文档&#xff0c;你来安排下」 项目中有这么一个需求&#xff0c;需要将用户…

Google 开源库Guava详解(集合工具类)—Maps、Multisets、Multimaps

一、Maps Maps有许多很酷的实用程序&#xff0c;值得单独解释。 1、uniqueIndex Maps.uniqueIndex&#xff08;Iterable&#xff0c;Function&#xff09;解决了一个常见的情况&#xff0c;即有一堆对象&#xff0c;每个对象都有一些唯一的属性&#xff0c;并希望能够根据该…

docker镜像详解

目录 什么是docker镜像镜像相关命令docker pulldocker imagesdocker searchdocker rmi导出 / 导入镜像 镜像分层镜像摘要镜像摘要的作用分发散列值 什么是docker镜像 Docker镜像是Docker容器的基础组件&#xff0c;它包含了运行一个应用程序所需的一切&#xff0c;包括代码、运…

JavaScript对象类型数据深拷贝方法【主要解决JSON.parse(JSON.stringify()会去掉函数属性的问题】

文章目录 JavaScript对象类型数据深拷贝方法【主要解决JSON.parse(JSON.stringify()会去掉函数属性的问题】手写对象类型数据深拷贝方法deepClone小结 JavaScript对象类型数据深拷贝方法【主要解决JSON.parse(JSON.stringify()会去掉函数属性的问题】 正常情况下&#xff0c;在…

win10 任务栏预览设置为列表效果

背景 在win10系统&#xff0c;当同一个应用&#xff08;如文件资源管理器&#xff0c;git bash&#xff0c;word等&#xff09;打开多个页面时&#xff0c;当个数少于17&#xff08;大约&#xff09;个时&#xff0c;其默认预览效果为平铺&#xff0c;在大于17个时&#xff0c…

Linux 中的 col 命令及示例

Linux 系统中的col命令用于过滤掉反向换行,使输出看起来更加正确,只有正向和半正向换行,并尽可能用制表符替换空白字符。这在处理 nroff 和 tbl 的输出时被证明是有用的。col 实用程序只是从标准输入读取并写入标准输出。 句法: 列 [-bfhpx] [-l num] col [-bfhpx] [-l nu…

【postgresql 基础入门】从了解数据库访问权限,访问数据库,到认识数据库的所有者及属性,从此打开了数据库使用的大门

数据库操作 ​专栏内容&#xff1a; postgresql内核源码分析手写数据库toadb并发编程 ​开源贡献&#xff1a; toadb开源库 个人主页&#xff1a;我的主页 管理社区&#xff1a;开源数据库 座右铭&#xff1a;天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君…

云备份——服务端客户端联合测试

一&#xff0c;准备工作 服务端清空备份文件信息、备份文件夹、压缩文件夹 客户端清空备份文件夹 二&#xff0c;开始测试 服务端配置文件 先启动服务端和客户端 向客户端指定文件夹放入稍微大点的文件&#xff0c;方便后续测试断点重传 2.1 上传功能测试 客户端自动上传成功…