【2025刷题笔记】- 分奖金

刷题笔记合集🔗

分奖金

问题描述

公司老板做了一笔大生意,想要给每位员工分配一些奖金,想通过游戏的方式来决定每个人分多少钱。

按照员工的工号顺序,每个人随机抽取一个数字。

按照工号的顺序往后排列,遇到第一个数字比自己数字大的,那么,前面的员工就可以获得"距离*数字差值"的奖金。

如果遇不到比自己数字大的,就给自己分配随机数数量的奖金。

例如,按照工号顺序的随机数字是:

那么第 个员工的数字 比第 个员工的数字 大,所以,第 个员工可以获得 的奖金。

个员工后面没有比他数字更大的员工,所以,他获得他分配的随机数数量的奖金,就是

个员工是最后一个员工,后面也没有比他更大数字的员工,所以他得到的奖金是

请帮老板计算一下每位员工最终分到的奖金都是多少钱。

输入格式

第一行 表示员工数量(包含最后一个老板)。

第二行是每位员工分配的随机数字。

输出格式

最终每位员工分到的奖金数量。

样例输入

3
2 10 3

样例输出

8 10 3

数据范围

  • 员工数量(包含老板)范围
  • 随机数范围
  • 随机数字不重复
样例 解释说明
样例1 第1个员工的随机数是2,第2个员工的随机数是10,差值是8,距离是1,所以第1个员工获得的奖金是8。
第2个员工的随机数是10,后面没有比他数字更大的员工,所以他获得他分配的随机数数量的奖金,即10。
第3个员工的随机数是3,是最后一个员工,后面没有其他员工,所以他获得他分配的随机数数量的奖金,即3。

题解

这道题要求计算每位员工分到的奖金,规则是:若员工后面有比自己数字更大的员工,则获得"距离*差值"的奖金;若没有,则获得自己随机数数量的奖金。

问题的核心是找到每个员工后面第一个比自己数字大的员工。这个问题可以有两种解法:

  1. 暴力解法:对于每个员工i,遍历i+1到n的所有员工,找到第一个比i大的。时间复杂度为O(n²)。
  2. 单调栈解法:使用单调栈以O(n)的复杂度找到每个员工的下一个更大元素。

考虑到员工数量最大可达10000,使用暴力解法可能会在极端测试用例下超时,所以这里介绍单调栈的解法。

单调栈是一种数据结构,栈中的元素保持单调递增或单调递减的顺序。我们可以用它来高效地找到数组中每个元素的下一个更大元素。

算法步骤:

  1. 初始化一个空栈stack和一个数组nextGreater,用于存储每个员工的下一个更大元素的索引(-1表示没有)。
  2. 从左到右遍历员工数组:
    • 当栈不为空,且当前员工的数字大于栈顶员工的数字时,栈顶元素找到了下一个更大的元素,即当前员工。更新nextGreater并弹出栈顶。
    • 将当前员工入栈。
  3. 最后,遍历数组,根据nextGreater计算每个员工的奖金。

这种方法的时间复杂度是O(n),空间复杂度也是O(n),对于给定的数据范围是高效的。

参考代码

  • Python
import sys
input = lambda:sys.stdin.readline().strip()

# 读取输入
n = int(input())
nums = list(map(int, input().split()))

# 使用单调栈计算每个员工的奖金
def calc_bonus(arr):
    """计算每个员工的奖金"""
    # 初始化单调栈和下一个更大元素数组
    stack = []
    next_greater = [-1] * len(arr)
    
    # 使用单调栈查找每个位置的下一个更大元素
    for i in range(len(arr)):
        # 当栈不为空且当前元素大于栈顶元素对应的值时
        while stack and arr[i] > arr[stack[-1]]:
            # 栈顶元素找到了下一个更大元素
            idx = stack.pop()
            next_greater[idx] = i
        # 当前索引入栈
        stack.append(i)
    
    # 计算奖金
    bonus = []
    for i in range(len(arr)):
        if next_greater[i] == -1:
            # 没有下一个更大元素,获得随机数数量的奖金
            bonus.append(arr[i])
        else:
            # 有下一个更大元素,获得距离*差值的奖金
            dist = next_greater[i] - i
            diff = arr[next_greater[i]] - arr[i]
            bonus.append(dist * diff)
    
    return " ".join(map(str, bonus))

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

算法刷题笔记 文章被收录于专栏

本专栏收集并整理了一些刷题笔记

全部评论

相关推荐

2025-12-19 20:49
门头沟学院 游戏测试
最开始年初的时候,一直在准备考研的东西,每天抱着张宇,考研英语,408就是一顿猛看,后来办了个学校健身房的卡,每天跟朋友一起约着下午学累了去锻炼一下,放松放松,就这样每天四点一线,宿舍-自习室-健身房-食堂-宿舍。后来学到了5月份,当时实在是有点疲惫了,看室友找到了小米的实习,我想着也去试试(尝试了一个月,相当痛苦),最开始选的都是一些像实施,技术支持类的工作,技术门槛相对较低,就疯狂往这方面整,后来面着面着发现测试也行,就又去投了测试,一直到上海的一家公司录用了我,我就决定放弃考研,去上海干游戏测试这个岗位的实习。最开始一天260(相当相当高了讲实话这个工资)后来老大觉得我干的挺好的,就跟hr说给我涨到了300一天。上海的花销也挺大,公司也不包饭,每个月干完最后就剩几百块了,最开始面对实习还是挺快乐的,毕竟不用整天面对408这些烦人的东西。后来就开始了秋招,也感谢旁边的两个哥教了我很多东西,对我的面试什么都有很大帮助。后来随着秋招的一次次一面挂,就萌生了要不搁这干着等转正的想法,一直到那个公司的老板开始抽风(疯狂加大工作量给测试),我都没想着要什么时候跑路,毕竟组里确实人都挺好的。后来到了九月份,之前面的几家公司相继给我过了面试发了意向我才真的确定我有了出路在这个秋招,于是开始了第一次跑路,九月底扔掉了押金,火速跑路回家休息了半个月,感觉干了三个月已经让我彻底对打工失去希望了,天天晚上九点多了才到家。后来十月和十一月去了广州的一家公司实习,也算是提前体验一下所谓的大公司怎么样。这两个月还是挺悠闲的,工位跟组里离得很远,也没人给我派什么活,每天就写写to-do-list,日报周报月报(挺shi的这个制度,后来都不知道怎么编了),玩玩手机一天天的就过去了,就是太无聊了,每天可以一句话都不说就过去了,感觉语言功能都快退化了,以至于跟对象打视频聊天的时候我说话都超多,可能憋太久不说话了。这两个月也攒了一些钱相对于上海(感谢广州。租房和吃饭什么的都比上海便宜很多,上海你就学吧)。12月回到了学校,终于是彻底的放松下来了
2025年终总结
点赞 评论 收藏
分享
查看13道真题和解析
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务