网上商城优惠活动-华为OD机试 2023

题目描述

解题思路

  1. 因为每人的优惠活动只有一次,92折只能用一次,无论92折券给了几张,都算一张
  2. 无门槛放在最后算,这样比先无门槛后满减或打折都省钱。
  3. 由于最多2种优惠券,且每种是一次使用,不能拆开使用。(比如用一张满减,再用一张打折,再用一张满减。)。结合第2条,6种组合只剩下4种,有:满减+打折,满减+无门槛,打折+满减,打折+无门槛
  4. 取价格最低,价格相同取优惠券少的那个。
  5. 需要考虑优惠券为0的情况

python代码

'''
解题思路
    1. 因为每人的优惠活动只有一次,92折只能用一次,无论92折券给了几张,都算一张。
    2. 无门槛放在最后算,这样比先无门槛后满减或打折都省钱。由于最多2种优惠券,且每种是一次使用,不能拆开使用。(比如用一张满减,再用一张打折,再用一张满减。)。
    3. 结合第2条,6种组合只剩下4种,有:满减+打折,满减+无门槛,打折+满减,打折+无门槛。
    4. 取价格最低,价格相同取优惠券少的那个。
    5. 需要考虑优惠券为0的情况
'''
'''满减'''
def mjf(p,n):
    # 返回张数,当前价格
    if n==0:
        return 0, p
    z = p // 100
    if n>=z:
        p = p - z*10
    else:
        p = p - n*10
        z = n
    return z, p
'''打折'''
def dzf(p,n):
    # 返回张数,当前价格
    if n==0:
        return 0, p
    z = 1
    if n>0:
        p = p*0.92
    return z, p
'''无门槛'''
def wmf(p, n):
    # 返回张数,当前价格
    if n==0:
        return 0, p
    if n>0:
        p = p-n*5
        z = n
    return z, p

'排列组合'
def arrange(lst):
    '''lst: list, 如[1,2,3], 返回6种全排列。
    返回全排列list
    '''
    '''1. 掉包方法'''
    # import itertools
    # res = list(itertools.permutations(lst))

    '''2. 不用掉包'''
    def permutations(lst):
        '''对于一个长度为n的列表,我们可以先将其中一个元素选出来作为第一个,然后对剩下的n-1个元素进行全排列,最后将第一个元素与每个全排列的结果组合起来,
        这个过程可以递归进行。'''
        if len(lst) == 1:
            return [lst]

        result = []
        for i in range(len(lst)):
            rest = lst[:i] + lst[i + 1:]  # 除了当前元素,其他所有的元素
            pailie = permutations(rest)
            for p in pailie:
                result.append([lst[i]] + p)
        return result

    res = permutations(lst) # [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
    return res


def cal(mj, dz, wm, p):
    # 生成不同的排列组合
    lst = [1,2,3] # 分别对应满减,打折,无门槛
    res = arrange(lst) # 因为只考虑四种情况,也可以手动写这4种。这里用全排列取了全部的6种,公式通用
    res = [i[:2] for i in res] # 只取前两个,因为是两种优惠券

    # 遍历所有的排列
    fton = {mjf:mj,dzf:dz,wmf:wm}
    dtof = {1:mjf,2:dzf,3:wmf}

    final_p = p
    final_z = 0
    for lst in res: # [1, 2,3]
        cur_p = p  # 当前价格
        cur_z = 0  # 当前优惠券张数
        for i in lst:
            z, cur_p = dtof[i](p=cur_p, n=fton[dtof[i]])
            cur_z += z # 张数累加
        # 比较每一组的价格,价格低的更新,相同价格取低的优惠券张数。
        if cur_p < final_p:
            final_p = cur_p
            final_z = cur_z
        elif cur_p == final_p:
            final_z = min(cur_z, final_z)

    return int(final_p), int(final_z)

# print(cal(3, 2, 5, 200))
mj, dz, wm = map(int, input().strip().split())
people_num = int(input().strip())
for i in range(people_num):
    p = int(input().strip())
    final_p, final_z = cal(mj, dz, wm, p)
    print(' '.join([str(final_p), str(final_z)]))

全部评论

相关推荐

字节 飞书绩效团队 (n+2) * 15 + 1k * 12 + 1w
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
11-20 19:57
已编辑
某大厂 golang工程师 23.0k*16.0, 2k房补,年终大概率能拿到
点赞 评论 收藏
分享
点赞 9 评论
分享
牛客网
牛客企业服务