华为OD机试真题 Python 实现【网上商城优惠活动(一)】【2022 Q4 100分】,附详细解题思路-LMLPHP

一、题目描述

某网上商城举办优惠活动,发布了满减、打折、无门槛3种优惠券,分别为:

1.每满100元优惠10元,无使用数限制,如100299可使用2张减20元,以此类推;
2.92折券,1次限使用1张,如100元,则优惠后为92元;
3.无门槛5元优惠券,无使用数限制,直接减5元。

每次最多使用2种优惠券,2种优惠可以叠加(优惠叠加时以优惠后的价格计算),以购物200元为例,可以先用92折券优惠到184元,再用1张满减券优惠10元,最终价格是174元,也可以用满减券2张优惠20元为180元,再使用92折券优惠到165(165.6向下取整)元,不同使用顺序的优惠价格不同,以最优惠价格为准。在一次购物中,同一类型优惠券使用多张时必须一次性使用,不能分多次拆开穿插使用(不允许先使用1张满减券,再用打折券,再使用一张满减券)。

请设计实现一种解决方法,帮助购物者以最少的优惠券获得最优的优惠价格。优惠后价格越低越好,同等优惠价格,使用的优惠券越少越好,可以允许某次购物不使用优惠券。

优惠活动每人只能参加一次,每个人的优惠券种类和数量是一样的。

二、输入描述

第一行:每个人拥有的优惠券数量(数量取值范围为[0, 10]),按满减、打折、无门槛的顺序输入。
第二行:表示购物的人数n(1 <= n <= 10000)。
最后n行:每一行表示某个人优惠前的购物总价格(价格取值范围(0, 1000],都为整数)。

约定:输入都是符合题目设定的要求的。

三、输出描述

每行输出每个人每次购物优惠后的最低价格以及使用的优惠券总数量,每行的输出顺序和输入的顺序保持一致。

四、补充说明

1.优惠券数量都为整数,取值范围为[0, 10]。
2.购物人数为整数,取值范围为[1, 10000]。
3.优惠券的购物总价为整数,取值范围为(0, 1000]。
4.优惠后价格如果是小数,则向下取整,输出都为整数。

五、Python算法源码

import sys
def get_min_price(price, c_1, c_2, c_3, d=1):
    if d > 2 or c_1 + c_2 + c_3 <= 0:
        return price, 0
    if price < 1:
        return 0, 0

    p = price
    c = 0
    if c_1 > 0:
        # 100-10
        c_num = min(price // 100, c_1)
        p_n = price - 10 * c_num
        p_t, c_t = get_min_price(p_n, 0, c_2, c_3, d + 1)
        if p_t < p:
            p = p_t
            c = c_t + c_num
        elif p_t == p and c_t + c_num < c:
            c = c_t + c_num

    if c_2 > 0:
        c_num = 1
        p_n = price * 0.92
        p_t, c_t = get_min_price(p_n, c_1, 0, c_3, d + 1)
        if p_t < p:
            p = p_t
            c = c_t + c_num
        elif p_t == p and c_t + c_num < c:
            c = c_t + c_num

    if c_3 > 0:
        c_num = min((price // 5) + 1, c_3)
        p_n = max(price - 5 * c_num, 0)
        p_t, c_t = get_min_price(p_n, c_1, c_2, 0, d + 1)
        if p_t < p:
            p = p_t
            c = c_t + c_num
        elif p_t == p and c_t + c_num < c:
            c = c_t + c_num
    return p, c


if __name__ == "__main__":
    # 读取第一行的n
    coupon_list = sys.stdin.readline().strip().split()
    c_1 = int(coupon_list[0])
    c_2 = int(coupon_list[1])
    c_3 = int(coupon_list[2])
    n = int(sys.stdin.readline().strip())
    ans = 0
    for i in range(n):
        # 读取每一行
        price = int(sys.stdin.readline().strip())
        # 把每一行的数字分隔后转化成int列表
        p_n, c_n = get_min_price(price, c_1, c_2, c_3)
        print(int(p_n), int(c_n))

六、效果展示

1、输入

3 2 5
3
100
200
400

2、输出

65 6
155 7
338 4

3、说明

输入3个人,输出3行结果,同输入的顺序,对应每个人的优惠结果,如下:
第一行:先使用1张满减券优惠到90元,再使用5张无门槛券优惠25元,最终价格是65元,总共使用6张优惠券
第二行:先使用2张满减券优惠到180元,再使用5张无门槛券优惠25元,最终价格是155元,总共使用7张优惠券
第三行:先使用1张92折券优惠到368元,再使用3张满减券优惠30元,最终价格是338元,总共使用4张优惠券


🏆下一篇:华为OD机试真题 Python 实现【相对开音节】【2022Q4 100分】,附详细解题思路

🏆本文收录于,华为OD机试(Python)真题(A卷+B卷)

刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,订阅后,专栏内的文章都可看,发现新题目,随时更新,全天CSDN在线答疑。

华为OD机试真题 Python 实现【网上商城优惠活动(一)】【2022 Q4 100分】,附详细解题思路-LMLPHP

07-06 02:11