如何向下取整奖金并按opt-in顺序分配剩余便士给同分玩家
奖金分配逻辑实现方案
核心前置处理
首先将源数据统一为结构化格式,从根源规避计算误差:
- 玩家列表:严格按照积分降序排列,每个玩家条目必须携带
player_id、points、opt_in_timestamp(opt-in完成的时间戳,数值越小代表完成时间越早)三个核心字段 - 奖金列表:严格按照排名升序排列,每个奖金条目携带
rank_position、prize_amount_cents字段——所有金额统一转换为最小货币单位(分)做整数计算,全程不使用浮点类型,彻底规避小数精度问题
同分分组与奖金池归集
按照“同分共享排名、跳过后续对应数量排名”的规则逐段处理玩家列表:
- 逐段遍历玩家列表,切分出所有同分小组:以当前未处理的第一个玩家为分组起点,统计所有和起点玩家积分完全一致的玩家,形成一个同分小组
- 计算该小组覆盖的排名区间:小组的起始排名
start_rank为小组第一个玩家对应的累计排名(即之前所有被处理小组的排名数累加值),小组因为有n_players名同分玩家,会连续跳过n_players个排名,覆盖区间为[start_rank, start_rank + n_players - 1] - 汇总奖金池:将奖金列表中,落在上述排名区间内的所有奖金金额求和,得到该小组的总可分配奖金
total_pool_cents - 累计当前已占用的排名数,移动到下一个未处理的玩家位置,重复上述分组流程直到遍历完所有玩家。
小组内奖金拆分
对每个同分小组的总奖金池,按规则完成拆分:
- 计算人均基础份额:对总奖金做整数除法,得到每个玩家的固定基础额度
base_per_player = total_pool_cents // n_players(该值为向下取整后的金额) - 计算可分配的零钱总额:
remaining_cents = total_pool_cents - base_per_player * n_players,也就是向下取整后剩余的零头分数 - 将小组内的玩家按
opt_in_timestamp从小到大排序(opt-in时间越早的排序越靠前) - 给排在排序列表前
remaining_cents位的玩家,每人额外发放1分,直到所有剩余零钱分配完毕。
示例验算(对应题目给出的场景)
- 分组情况:3名200分的玩家形成一个同分小组,
n_players=3,起始排名为3,覆盖排名区间3-5,总奖金池为Rank3对应的25001分(即250.01美元) - 基础份额计算:
base_per_player = 25001 // 3 = 8333分(即83.33美元) - 剩余零钱计算:
remaining_cents = 25001 - 8333 *3 =2分 - 按opt-in顺序排序:Player1 > Player5 > Player2(时间从早到晚)
- 额外零钱发放:前2名(Player1、Player5)各加1分,最终分配结果为Player1=8334分(83.34美元)、Player5=8334分(83.34美元)、Player2=8333分(83.33美元),和规则要求完全匹配。
内容的提问来源于stack exchange,提问作者Monku
相关产品推荐
相关产品推荐

