华为OD机考算法题:分奖金

2023-09-11 23:45:00

题目部分

题目分奖金
难度
题目说明公司老板做了一笔大生意,想要给每位员工分配一些奖金,想通过游戏的方式来决定每个人分多少钱。按照员工的工号顺序,每个人随机抽取一个数字。按照工号的顺序往后排列,遇到第一个数字比自己数字大的,那么,前面的员工就可以获得 距离 * 数字差值 的奖金。如果遇不到比自己数字大的,就给自己分配随机数数量的奖金。例如,按照工号顺序的随机数字是:2,10,3。那么第 2 个员工的数字 10 比第 1 个员工的数字 2 大,所以,第 1 个员工可以获得 1 * (10 - 2) = 8。第 2 个员工后面没有比他数字更大的员工,所以,他获得他分配的随机数数量的奖金,就是 10。第 3 个员工是最后一个员工,后面也没有比他更大数字的员工,所以他得到的奖金是 3。
请帮老板计算一下每位员工最终分到的奖金都是多少钱。
输入描述第一行 n 表示员工数量(包含最后一个老板)。
第二是每位员工分配的随机数字。
例如:
3
2 10 3
输出描述最终每位员工分到的奖金数量。
例如:
8 10 3
补充说明随机数字不重复,员工数量(包含老板)范围 1 ~ 10000,随机数范围 1 ~ 100000。
------------------------------------------------------
示例
示例1
输入3
2 10 3
输出8 10 3
说明


解读与分析

题目解读

分奖金时,员工先按照员工号排序。每位员工的奖金数与工号更大的员工抽取的数字相关,与工号小的员工没有关系。

此题可翻译成:有一个整形数组,设为 arr,其长度为 n,数组个元素已经初始化为指定的值。对于数组中第 i (0 ≤ i < n)个元素,如果:
1. 在第 ( i + 1 ) 到 n 个元素中存在比 arr[i] 大的元素,如果这样的元素有多个,取其下标最小的一个元素。假设下标最小的元素其下标为 j,那么 arr[i] 的值修改为 ( arr[j] - arr[i] ) * ( j - i)。
2. 
在第 ( i + 1 ) 到 n 个元素中存在比 arr[i] 大的元素,那么 arr[i] 的值保持不变。
遍历完数组 arr 之后,输出数组 arr 的内容。

分析与思路

虽然此题的难度为“难”,解题思路和算法却都非常简单。

我们可以直接从第 0 个元素开始往后遍历,根据题目解读中提到的两种情况,逐一刷新每个元素的值。因为每个元素的最终值只与排在它后面的元素有关,所以一定要从第 0 个元素开始遍历,而不能从最后一个元素 (n - 1) 开始遍历。

在遍历过程中,最坏的情况需遍历 n! 次元素,此算法的时间复杂度 O(n!);整个遍历过程只使用了原始数据类型变量,且空间与数组长度无关,此算法的空间复杂度为 O(1)。


代码实现

Java代码

import java.util.Scanner;

/**
 * 分奖金
 * @since 2023.09.11
 * @version 0.1
 * @author Frank
 *
 */
public class BonusDistribution {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while (sc.hasNext()) {
			String input = sc.nextLine();
			int count = Integer.parseInt( input );
			input = sc.nextLine();
			String[] numbers = input.split( " " );
			// 此处 count == numbers.count,可以完全不用考虑 count.
			processBonusDistribution( numbers );
		}

	}
	
	private static void processBonusDistribution( String numbers[] )
	{
		int[] arr = arrString2Int( numbers );
		for( int i = 0; i < arr.length; i ++ )
		{
			for( int j = i + 1; j < arr.length; j ++ )
			{
				if( arr[j] > arr[i] )
				{
					arr[i] = ( arr[j] - arr[i] ) * ( j - i );
					break;
				}
			}
		}
		
		StringBuffer sb = new StringBuffer();
		for( int i = 0; i < arr.length; i ++ )
		{
			if( i != arr.length - 1 )
			{
				sb.append( arr[i] + " " );
			}else
			{
				sb.append( arr[i] );
			}
		}
		System.out.println( sb.toString() );
	}
	
	private static int[] arrString2Int( String numbers[] )
	{
		int ret[] = new int[numbers.length];
		for( int i = 0; i < numbers.length; i ++ )
		{
			ret[i] = Integer.parseInt( numbers[i] );
		}
		return ret;
	}

}

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()) {
        // count 可以忽略
        var count = parseInt(line);
        line = await readline();
        var numberArr = line.split(" ");
        processBonusDistribution(numberArr);
    }
}();

function processBonusDistribution(numberArr) {
        var arr = arrString2Int( numberArr );
        for( var i = 0; i < arr.length; i ++ )
        {
            for( var j = i + 1; j < arr.length; j ++ )
            {
                if( arr[j] > arr[i] )
                {
                    arr[i] = ( arr[j] - arr[i] ) * ( j - i );
                    break;
                }
            }
        }
        console.log( arr.join(" "));
}

function arrString2Int( numberArr )
{
    var ret = [];
    for( var i = 0; i < numberArr.length; i ++)
    {
        ret.push( parseInt( numberArr[i] ) );
    }
    return ret;
}

(完)

更多推荐

Python--函数

目录1、定义函数1.1向函数传递信息1.2实参和形参2、传递实参2.1位置实参2.2关键字实参2.3默认值2.4等效的函数调用2.5避免实参错误3、返回值3.1返回简单的值3.2让实参变成可选的3.3返回字典3.4结合使用函数和While循环4、传递列表4.1在函数中修改列表4.2禁止函数修改列表5、传递任意数量的实参

C++学习笔记——类与对象(六个默认成员函数)

1、构造函数在一个类中,编译器会自动生成默认的成员函数,当对象进行初始化时,会默认调用这个函数来初始化。构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,以保证每个数据成员都有一个合适的初始值,并且在对象整个生命周期内只调用一次。它的特点是:没有返回值系统自动调用构造函数可以重载名字和类名

简单工厂模式 和 工厂方法 和 抽象工厂的区别

简单工厂模式、工厂方法模式和抽象工厂模式是三种不同的创建型设计模式,它们在对象的创建和封装方面有不同的用途和实现方式。以下是它们之间的主要区别:1.**简单工厂模式(SimpleFactoryPattern)**:-**目的**:简单工厂模式的主要目的是封装对象的创建逻辑,以便客户端代码无需知道具体对象的创建细节。它将

展会预告 | 图扑邀您共聚 IOTE 国际物联网展·深圳站

参展时间:9月20日-22日图扑展位:9号馆9B35-1参展地址:深圳国际会展中心(宝安新馆)IOTE2023第二十届国际物联网展·深圳站,将于9月20日-22日在深圳国际会展中心(宝安)9、10、11号馆震撼来袭。本届展会以“IoT构建数字经济底座”为主题,将IoT技术引入实体经济领域,促进数字化转型和智能化升级,推

基于Java+SpringBoot+Vue前后端分离旅游网站设计和实现

博主介绍:✌全网粉丝30W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌🍅文末获取源码联系🍅👇🏻精彩专栏推荐订阅👇🏻不然下次找不到哟2022-2024年最全的计算机软件毕业设计选题

基于Java旅游管理系统设计实现(源码+lw+部署文档+讲解等)

博主介绍:✌全网粉丝30W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌🍅文末获取源码联系🍅👇🏻精彩专栏推荐订阅👇🏻不然下次找不到哟2022-2024年最全的计算机软件毕业设计选题

python经典百题之最大公约数与最小公倍数

题目:输入两个正整数m和n,求其最大公约数和最小公倍数。方法1:辗转相除法(欧几里德算法)求最大公约数defgcd_euclidean(m,n):whilen:m,n=n,m%nreturnmm=36n=48gcd_result=gcd_euclidean(m,n)print("GCD:",gcd_result)#计算

echarts-可视化地图防重叠文本框

我在第一篇可视化地图中,有一些基础介绍,本篇文章就是多展示一些效果,大家可以按需获取。先直接上效果图这里的配置项有用到1、通过geo展示多层地图,这样可以像上图所示,通过错位有了一些3D效果;2、北京的特殊图标展示通过scatter类型实现;3、区域散点图effectScatter类型;4、有方向流动的线,lines类

Vue2023 面试归纳及复习(2)

1vue3中的动态组件和KeepAlive组件动态组件component<component>动态组件是一种可以根据数据变化而动态加载不同组件的方式。使用动态组件可以有效地减少代码复杂度,提高组件的复用性和灵活性。动态组件通过一个特殊的属性is来实现动态加载,is的值可以是组件的名称或组件对象。KeepAliveKee

设计模式-责任链模式

“单一职责原则”要求一个类仅负责的一个不可分业务逻辑,但这并不意味着能够实现这部分业务逻辑的只能有一个类,业务逻辑可能是会因运行时数据而选择不同类。比如在日常工作中,请假审批可能受请假天数、请假类型等因素影响,而须由不同领导来负责审批。再比如在银行取钱时,取钱业务审批申请可能会受到你所取钱总数、存储类型等因素影响,而须

node 之 express 框架(初级)

一、express热更新1、安装扩展npminstallnode-dev-D2、在根目录下的package.json文件中进行配置3、之后的启动执行下面的命令即可npmrundev二、mvc中的模板引擎1、ejs模板引擎的安装npminstallejs-s2、在根目录下的app.js文件中配置app.set('view

热文推荐