【网上商城优惠活动】

【背景】
某网上商城举办优惠活动,发布了满减、打折、无门槛3 种优惠券,分别为:
1.每满100 元优惠10 元,无使用数限制,如100~199 元可以使用1 张减10 元,200~299 可使用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],都为整数)。
约定:输入都是符合题目设定的要求的。
输出描述
每行输出每个人每次购物优惠后的最低价格以及使用的优惠券总数量,每行的输出顺序和
输入的顺序保持一致。

import math
m,d,w = map(int,input().split())
n = int(input())
prices = [int(input()) for i in range(n)]

#定义满减
def manJian(price,m):
    '需要判断是否执行满减'
    maxCount = price//100#理论上最多满减券,实际数量可能小于这个
    count = min(m,maxCount)#实际能用的满减券
    price -= count * 10
    m -= count
    return price,m

def daZhe(price,d):
    if d >= 1:
        price = math.floor(price*0.92)
    return price,d-1

def wuMenKan(price,w):
    while  price > 0 and w > 0:
        price -= 5
        price = max(0,price)#价格最少为0,不能为负数
        w -= 1
    return price,w


for price in prices:
    ret = []

    resM = manJian(price, m)  # 先满减

    resMN_N = daZhe(resM[0], d)  # 满减后打折
    ret.append((resMN_N[0], m + d - (resM[1] + resMN_N[1])))  # m + n 是满减后打折方式的总券数量, resM[1] + resMN_N[1] 是满减券剩余数+打折券剩余数

    resMK_K = wuMenKan(resM[0], w)  # 满减后无门槛
    ret.append((resMK_K[0], m + w - (resM[1] + resMK_K[1])))

    resN = daZhe(price, d)  # 先打折

    resNM_M = manJian(resN[0], m)  # 打折后满减
    ret.append((resNM_M[0], d + m - (resN[1] + resNM_M[1])))

    resNK_K = wuMenKan(resN[0], w)  # 打折后无门槛
    ret.append((resNK_K[0], d + w - (resN[1] + resNK_K[1])))

    '''
    先用无门槛后打折(x-5y)*0.92 = x*0.92 - 5*0.92*y
    先打折后用无门槛 x*0.92 - 5y
    对比可以看出,先92折,再无门槛最优惠,因此可以直接排除即先无门槛的情况。
    '''

    # 对ans进行排序,排序规则是:优先按剩余总价升序,如果剩余总价相同,则再按“使用掉的券数量”升序
    ret.sort(key=lambda x: (x[0], x[1]))
    #print(ret)

    print(" ".join(map(str, ret[0])))







  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值