华为OD机试 - 模拟商场优惠打折II - 穷举(Python/JS/C/C++ 2024 E卷 100分)

在这里插入图片描述

华为OD机试 2024E卷题库疯狂收录中,刷题点这里

专栏导读

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

一、题目描述

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

1.每满100元优惠10元,无使用数限制,如100199元可以使用1张减10元,200299可使用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. 优惠后价格如果是小数,则向下取整,输出都为整数。

四、测试用例

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张优惠券

五、解题思路

1、题目分析

题目要求根据一组优惠券,找到每个人的购物总价格在使用优惠券后的最低价格,并且在价格相同的情况下,优先使用最少数量的优惠券。题目中有三种优惠券:

  1. 满减券:每满100元减10元,可以使用多张。
  2. 打折券:92折券,每次限使用一张。
  3. 无门槛5元优惠券:可以使用多张。

同时,每次最多可以使用两种优惠券组合,优惠券的使用顺序会影响最终的价格,因此需要考虑使用顺序不同的情况,并在所有情况下找到最低的价格。

2、解题思路

我们可以将此问题视为多重优惠组合下的最优化问题,核心任务是通过遍历优惠券的所有使用情况,找到在所有组合下的最低价格。由于每个人的初始购物价格、满减、打折和5元优惠券的使用情况都不同,需要分别对每个人计算最终优惠后的价格。

主要的解题步骤包括:

  1. 计算单种优惠券的最低价格:
    • 分别计算在只使用满减券、只使用打折券、只使用5元无门槛券的情况下,购物后的最低价格。
  2. 计算两种优惠券的组合:
    • 计算使用满减券+打折券、满减券+5元无门槛券、打折券+5元无门槛券的组合情况。需要考虑两种优惠券的使用顺序,因为顺序不同,结果也会不同。
  3. 选择最优解:
    • 从所有可能的优惠券使用情况中,选择最终价格最低的组合。如果多个组合价格相同,则优先选择使用优惠券数量较少的组合。

3、暴力搜索与穷举法

该问题的核心在于,找到所有可能的优惠券使用组合并计算其价格,最后从这些组合中找到最低的价格。

暴力搜索:我们通过暴力搜索的方式枚举所有可能的优惠券使用顺序和组合。在这种情况下,需要考虑单一优惠券和两种优惠券的组合。
穷举法:对每种优惠券及其组合方式进行穷举,计算在每种情况下的最终价格。穷举的目的是考虑所有可能的优惠券使用顺序,从而确保能够找到最低的价格。

由于优惠券数量有限(最多10张),穷举法的复杂度是可接受的,尤其当我们需要考虑购物人数多的情况。

六、Python算法源码

# 导入必要的库
import sys
import math

def calculate_min_price(price, full_reduction, discounts, coupons):
    """
    计算每个人购物后的最低价格和使用的优惠券数量

    :param price: 原始购物价格
    :param full_reduction: 满减券数量
    :param discounts: 打折券数量
    :param coupons: 无门槛5元优惠券数量
    :return: 最低价格和使用的优惠券数量
    """
    # 初始化最优价格为原价,不使用任何优惠券
    min_price = price
    min_coupons_used = 0

    # 使用一张优惠券的情况
    # 1. 仅使用满减券
    if full_reduction > 0:
        # 计算可以使用的满减券数量
        num_full_reduction = min(full_reduction, price // 100)
        # 计算使用满减券后的价格
        price_after_full = price - 10 * num_full_reduction
        # 更新最优价格和使用的优惠券数量
        if price_after_full < min_price or (price_after_full == min_price and num_full_reduction < min_coupons_used):
            min_price = price_after_full
            min_coupons_used = num_full_reduction

    # 2. 仅使用打折券
    if discounts > 0:
        # 计算使用打折券后的价格,并向下取整
        price_after_discount = math.floor(price * 0.92)
        # 使用一张打折券
        if price_after_discount < min_price or (price_after_discount == min_price and 1 < min_coupons_used):
            min_price = price_after_discount
            min_coupons_used = 1

    # 3. 仅使用无门槛5元优惠券
    if coupons > 0:
        # 计算可以使用的5元优惠券数量
        num_coupons = min(coupons, price // 5)
        # 计算使用5元优惠券后的价格
        price_after_coupon = price - 5 * num_coupons
        # 更新最优价格和使用的优惠券数量
        if price_after_coupon < min_price or (price_after_coupon == min_price and num_coupons < min_coupons_used):
            min_price = price_after_coupon
            min_coupons_used = num_coupons

    # 使用两种优惠券的情况
    # 1. 满减券 + 打折券
    if full_reduction > 0 and discounts > 0:
        # 先使用满减券,再使用打折券
        num_full_reduction = min(full_reduction, price // 100)
        price_after_full = price - 10 * num_full_reduction
        price_after_full_discount = math.floor(price_after_full * 0.92)
        total_coupons = num_full_reduction + 1
        if price_after_full_discount < min_price or (price_after_full_discount == min_price and total_coupons < min_coupons_used):
            min_price = price_after_full_discount
            min_coupons_used = total_coupons

        # 先使用打折券,再使用满减券
        price_after_discount = math.floor(price * 0.92)
        num_full_reduction_discount = min(full_reduction, price_after_discount // 100)
        price_after_discount_full = price_after_discount - 10 * num_full_reduction_discount
        total_coupons_discount = 1 + num_full_reduction_discount
        if price_after_discount_full < min_price or (price_after_discount_full == min_price and total_coupons_discount < min_coupons_used):
            min_price = price_after_discount_full
            min_coupons_used = total_coupons_discount

    # 2. 满减券 + 无门槛5元优惠券
    if full_reduction > 0 and coupons > 0:
        # 先使用满减券,再使用5元优惠券
        num_full_reduction = min(full_reduction, price // 100)
        price_after_full = price - 10 * num_full_reduction
        num_coupons = min(coupons, price_after_full // 5)
        price_after_full_coupon = price_after_full - 5 * num_coupons
        total_coupons_full = num_full_reduction + num_coupons
        if price_after_full_coupon < min_price or (price_after_full_coupon == min_price and total_coupons_full < min_coupons_used):
            min_price = price_after_full_coupon
            min_coupons_used = total_coupons_full

        # 先使用5元优惠券,再使用满减券
        num_coupons_first = min(coupons, price // 5)
        price_after_coupon_first = price - 5 * num_coupons_first
        num_full_reduction_second = min(full_reduction, price_after_coupon_first // 100)
        price_after_coupon_full = price_after_coupon_first - 10 * num_full_reduction_second
        total_coupons_second = num_coupons_first + num_full_reduction_second
        if price_after_coupon_full < min_price or (price_after_coupon_full == min_price and total_coupons_second < min_coupons_used):
            min_price = price_after_coupon_full
            min_coupons_used = total_coupons_second

    # 3. 打折券 + 无门槛5元优惠券
    if discounts > 0 and coupons > 0:
        # 先使用打折券,再使用5元优惠券
        price_after_discount = math.floor(price * 0.92)
        num_coupons = min(coupons, price_after_discount // 5)
        price_after_discount_coupon = price_after_discount - 5 * num_coupons
        total_coupons_discount = 1 + num_coupons
        if price_after_discount_coupon < min_price or (price_after_discount_coupon == min_price and total_coupons_discount < min_coupons_used):
            min_price = price_after_discount_coupon
            min_coupons_used = total_coupons_discount

        # 先使用5元优惠券,再使用打折券
        num_coupons_first = min(coupons, price // 5)
        price_after_coupon_first = price - 5 * num_coupons_first
        price_after_coupon_discount = math.floor(price_after_coupon_first * 0.92)
        total_coupons_second = num_coupons_first + 1
        if price_after_coupon_discount < min_price or (price_after_coupon_discount == min_price and total_coupons_second < min_coupons_used):
            min_price = price_after_coupon_discount
            min_coupons_used = total_coupons_second

    return min_price, min_coupons_used

def main():
    # 读取输入
    # 第一行:满减券数量,打折券数量,无门槛5元优惠券数量
    coupons = list(map(int, sys.stdin.readline().strip().split()))
    full_reduction = coupons[0]
    discounts = coupons[1]
    coupons_5 = coupons[2]

    # 第二行:购物人数
    n = int(sys.stdin.readline().strip())

    # 读取每个人的购物总价格
    prices = []
    for _ in range(n):
        price = int(sys.stdin.readline().strip())
        prices.append(price)

    # 对每个人的价格进行计算并输出结果
    for price in prices:
        min_price, coupons_used = calculate_min_price(price, full_reduction, discounts, coupons_5)
        # 确保价格不低于0
        min_price = max(min_price, 0)
        print(f"{min_price} {coupons_used}")

if __name__ == "__main__":
    main()

七、JavaScript算法源码

// 导入必要的模块
const readline = require('readline');

// 创建接口实例用于读取输入
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

// 存储输入的行
let inputLines = [];

// 监听每一行输入
rl.on('line', (line) => {
    inputLines.push(line.trim());
}).on('close', () => {
    // 处理输入数据
    // 第一行:满减券数量,打折券数量,无门槛5元优惠券数量
    const coupons = inputLines[0].split(' ').map(Number);
    const fullReduction = coupons[0]; // 满减券数量
    const discounts = coupons[1];     // 打折券数量
    const coupons5 = coupons[2];       // 无门槛5元优惠券数量

    // 第二行:购物人数
    const n = parseInt(inputLines[1]);

    // 接下来n行:每个人的购物总价格
    const prices = [];
    for(let i = 0; i < n; i++) {
        prices.push(parseInt(inputLines[2 + i]));
    }

    // 定义计算最低价格和使用优惠券数量的函数
    function calculateMinPrice(price, fullReduction, discounts, coupons5) {
        // 初始化最优价格为原价,不使用任何优惠券
        let minPrice = price;
        let minCouponsUsed = 0;

        // 使用一张优惠券的情况
        // 1. 仅使用满减券
        if(fullReduction > 0){
            // 计算可以使用的满减券数量
            let numFullReduction = Math.min(fullReduction, Math.floor(price / 100));
            // 计算使用满减券后的价格
            let priceAfterFull = price - 10 * numFullReduction;
            // 更新最优价格和使用的优惠券数量
            if(priceAfterFull < minPrice || (priceAfterFull === minPrice && numFullReduction < minCouponsUsed)){
                minPrice = priceAfterFull;
                minCouponsUsed = numFullReduction;
            }
        }

        // 2. 仅使用打折券
        if(discounts > 0){
            // 计算使用打折券后的价格,并向下取整
            let priceAfterDiscount = Math.floor(price * 0.92);
            // 使用一张打折券
            if(priceAfterDiscount < minPrice || (priceAfterDiscount === minPrice && 1 < minCouponsUsed)){
                minPrice = priceAfterDiscount;
                minCouponsUsed = 1;
            }
        }

        // 3. 仅使用无门槛5元优惠券
        if(coupons5 > 0){
            // 计算可以使用的5元优惠券数量
            let numCoupons = Math.min(coupons5, Math.floor(price / 5));
            // 计算使用5元优惠券后的价格
            let priceAfterCoupon = price - 5 * numCoupons;
            // 更新最优价格和使用的优惠券数量
            if(priceAfterCoupon < minPrice || (priceAfterCoupon === minPrice && numCoupons < minCouponsUsed)){
                minPrice = priceAfterCoupon;
                minCouponsUsed = numCoupons;
            }
        }

        // 使用两种优惠券的情况
        // 1. 满减券 + 打折券
        if(fullReduction > 0 && discounts > 0){
            // 先使用满减券,再使用打折券
            let numFullReduction = Math.min(fullReduction, Math.floor(price / 100));
            let priceAfterFull = price - 10 * numFullReduction;
            let priceAfterFullDiscount = Math.floor(priceAfterFull * 0.92);
            let totalCoupons = numFullReduction + 1;
            if(priceAfterFullDiscount < minPrice || (priceAfterFullDiscount === minPrice && totalCoupons < minCouponsUsed)){
                minPrice = priceAfterFullDiscount;
                minCouponsUsed = totalCoupons;
            }

            // 先使用打折券,再使用满减券
            let priceAfterDiscount = Math.floor(price * 0.92);
            let numFullReductionDiscount = Math.min(fullReduction, Math.floor(priceAfterDiscount / 100));
            let priceAfterDiscountFull = priceAfterDiscount - 10 * numFullReductionDiscount;
            let totalCouponsDiscount = 1 + numFullReductionDiscount;
            if(priceAfterDiscountFull < minPrice || (priceAfterDiscountFull === minPrice && totalCouponsDiscount < minCouponsUsed)){
                minPrice = priceAfterDiscountFull;
                minCouponsUsed = totalCouponsDiscount;
            }
        }

        // 2. 满减券 + 无门槛5元优惠券
        if(fullReduction > 0 && coupons5 > 0){
            // 先使用满减券,再使用5元优惠券
            let numFullReduction = Math.min(fullReduction, Math.floor(price / 100));
            let priceAfterFull = price - 10 * numFullReduction;
            let numCoupons = Math.min(coupons5, Math.floor(priceAfterFull /5));
            let priceAfterFullCoupon = priceAfterFull - 5 * numCoupons;
            let totalCouponsFull = numFullReduction + numCoupons;
            if(priceAfterFullCoupon < minPrice || (priceAfterFullCoupon === minPrice && totalCouponsFull < minCouponsUsed)){
                minPrice = priceAfterFullCoupon;
                minCouponsUsed = totalCouponsFull;
            }

            // 先使用5元优惠券,再使用满减券
            let numCouponsFirst = Math.min(coupons5, Math.floor(price /5));
            let priceAfterCouponFirst = price -5 * numCouponsFirst;
            let numFullReductionSecond = Math.min(fullReduction, Math.floor(priceAfterCouponFirst /100));
            let priceAfterCouponFull = priceAfterCouponFirst -10 * numFullReductionSecond;
            let totalCouponsSecond = numCouponsFirst + numFullReductionSecond;
            if(priceAfterCouponFull < minPrice || (priceAfterCouponFull === minPrice && totalCouponsSecond < minCouponsUsed)){
                minPrice = priceAfterCouponFull;
                minCouponsUsed = totalCouponsSecond;
            }
        }

        // 3. 打折券 + 无门槛5元优惠券
        if(discounts >0 && coupons5 >0){
            // 先使用打折券,再使用5元优惠券
            let priceAfterDiscount = Math.floor(price *0.92);
            let numCoupons = Math.min(coupons5, Math.floor(priceAfterDiscount /5));
            let priceAfterDiscountCoupon = priceAfterDiscount -5 * numCoupons;
            let totalCouponsDiscount =1 + numCoupons;
            if(priceAfterDiscountCoupon < minPrice || (priceAfterDiscountCoupon === minPrice && totalCouponsDiscount < minCouponsUsed)){
                minPrice = priceAfterDiscountCoupon;
                minCouponsUsed = totalCouponsDiscount;
            }

            // 先使用5元优惠券,再使用打折券
            let numCouponsFirst = Math.min(coupons5, Math.floor(price /5));
            let priceAfterCouponFirst = price -5 * numCouponsFirst;
            let priceAfterCouponDiscount = Math.floor(priceAfterCouponFirst *0.92);
            let totalCouponsSecond = numCouponsFirst +1;
            if(priceAfterCouponDiscount < minPrice || (priceAfterCouponDiscount === minPrice && totalCouponsSecond < minCouponsUsed)){
                minPrice = priceAfterCouponDiscount;
                minCouponsUsed = totalCouponsSecond;
            }
        }

        return [Math.max(minPrice,0), minCouponsUsed];
    }

    // 对每个人的价格进行计算并输出结果
    prices.forEach(price => {
        const [minPrice, couponsUsed] = calculateMinPrice(price, fullReduction, discounts, coupons5);
        console.log(`${minPrice} ${couponsUsed}`);
    });
});

八、C算法源码

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

// 定义一个结构体用于存储结果
typedef struct {
    int min_price;      // 最低价格
    int coupons_used;   // 使用的优惠券数量
} Result;

// 函数声明
Result calculate_min_price(int price, int full_reduction, int discounts, int coupons5);

int main(){
    int full_reduction, discounts, coupons5;
    // 读取第一行:满减券数量,打折券数量,无门槛5元优惠券数量
    scanf("%d %d %d", &full_reduction, &discounts, &coupons5);

    int n;
    // 读取第二行:购物人数
    scanf("%d", &n);

    // 读取每个人的购物总价格并计算结果
    for(int i =0; i <n; i++){
        int price;
        scanf("%d", &price);
        Result res = calculate_min_price(price, full_reduction, discounts, coupons5);
        // 确保价格不低于0
        if(res.min_price <0){
            res.min_price =0;
        }
        printf("%d %d\n", res.min_price, res.coupons_used);
    }

    return 0;
}

// 计算每个人的最低价格和使用的优惠券数量
Result calculate_min_price(int price, int full_reduction, int discounts, int coupons5){
    Result res;
    // 初始化最优价格为原价,不使用任何优惠券
    res.min_price = price;
    res.coupons_used =0;

    // 使用一张优惠券的情况
    // 1. 仅使用满减券
    if(full_reduction >0){
        // 计算可以使用的满减券数量
        int num_full_reduction = full_reduction < (price /100) ? full_reduction : (price /100);
        // 计算使用满减券后的价格
        int price_after_full = price -10 * num_full_reduction;
        // 更新最优价格和使用的优惠券数量
        if(price_after_full < res.min_price || (price_after_full == res.min_price && num_full_reduction < res.coupons_used)){
            res.min_price = price_after_full;
            res.coupons_used = num_full_reduction;
        }
    }

    // 2. 仅使用打折券
    if(discounts >0){
        // 计算使用打折券后的价格,并向下取整
        int price_after_discount = floor(price *0.92);
        // 使用一张打折券
        if(price_after_discount < res.min_price || (price_after_discount == res.min_price && 1 < res.coupons_used)){
            res.min_price = price_after_discount;
            res.coupons_used =1;
        }
    }

    // 3. 仅使用无门槛5元优惠券
    if(coupons5 >0){
        // 计算可以使用的5元优惠券数量
        int num_coupons = coupons5 < (price /5) ? coupons5 : (price /5);
        // 计算使用5元优惠券后的价格
        int price_after_coupon = price -5 * num_coupons;
        // 更新最优价格和使用的优惠券数量
        if(price_after_coupon < res.min_price || (price_after_coupon == res.min_price && num_coupons < res.coupons_used)){
            res.min_price = price_after_coupon;
            res.coupons_used = num_coupons;
        }
    }

    // 使用两种优惠券的情况
    // 1. 满减券 + 打折券
    if(full_reduction >0 && discounts >0){
        // 先使用满减券,再使用打折券
        int num_full_reduction = full_reduction < (price /100) ? full_reduction : (price /100);
        int price_after_full = price -10 * num_full_reduction;
        int price_after_full_discount = floor(price_after_full *0.92);
        int total_coupons = num_full_reduction +1;
        if(price_after_full_discount < res.min_price || (price_after_full_discount == res.min_price && total_coupons < res.coupons_used)){
            res.min_price = price_after_full_discount;
            res.coupons_used = total_coupons;
        }

        // 先使用打折券,再使用满减券
        int price_after_discount = floor(price *0.92);
        int num_full_reduction_discount = full_reduction < (price_after_discount /100) ? full_reduction : (price_after_discount /100);
        int price_after_discount_full = price_after_discount -10 * num_full_reduction_discount;
        int total_coupons_discount =1 + num_full_reduction_discount;
        if(price_after_discount_full < res.min_price || (price_after_discount_full == res.min_price && total_coupons_discount < res.coupons_used)){
            res.min_price = price_after_discount_full;
            res.coupons_used = total_coupons_discount;
        }
    }

    // 2. 满减券 + 无门槛5元优惠券
    if(full_reduction >0 && coupons5 >0){
        // 先使用满减券,再使用5元优惠券
        int num_full_reduction = full_reduction < (price /100) ? full_reduction : (price /100);
        int price_after_full = price -10 * num_full_reduction;
        int num_coupons = coupons5 < (price_after_full /5) ? coupons5 : (price_after_full /5);
        int price_after_full_coupon = price_after_full -5 * num_coupons;
        int total_coupons_full = num_full_reduction + num_coupons;
        if(price_after_full_coupon < res.min_price || (price_after_full_coupon == res.min_price && total_coupons_full < res.coupons_used)){
            res.min_price = price_after_full_coupon;
            res.coupons_used = total_coupons_full;
        }

        // 先使用5元优惠券,再使用满减券
        int num_coupons_first = coupons5 < (price /5) ? coupons5 : (price /5);
        int price_after_coupon_first = price -5 * num_coupons_first;
        int num_full_reduction_second = full_reduction < (price_after_coupon_first /100) ? full_reduction : (price_after_coupon_first /100);
        int price_after_coupon_full = price_after_coupon_first -10 * num_full_reduction_second;
        int total_coupons_second = num_coupons_first + num_full_reduction_second;
        if(price_after_coupon_full < res.min_price || (price_after_coupon_full == res.min_price && total_coupons_second < res.coupons_used)){
            res.min_price = price_after_coupon_full;
            res.coupons_used = total_coupons_second;
        }
    }

    // 3. 打折券 + 无门槛5元优惠券
    if(discounts >0 && coupons5 >0){
        // 先使用打折券,再使用5元优惠券
        int price_after_discount = floor(price *0.92);
        int num_coupons = coupons5 < (price_after_discount /5) ? coupons5 : (price_after_discount /5);
        int price_after_discount_coupon = price_after_discount -5 * num_coupons;
        int total_coupons_discount =1 + num_coupons;
        if(price_after_discount_coupon < res.min_price || (price_after_discount_coupon == res.min_price && total_coupons_discount < res.coupons_used)){
            res.min_price = price_after_discount_coupon;
            res.coupons_used = total_coupons_discount;
        }

        // 先使用5元优惠券,再使用打折券
        int num_coupons_first = coupons5 < (price /5) ? coupons5 : (price /5);
        int price_after_coupon_first = price -5 * num_coupons_first;
        int price_after_coupon_discount = floor(price_after_coupon_first *0.92);
        int total_coupons_second = num_coupons_first +1;
        if(price_after_coupon_discount < res.min_price || (price_after_coupon_discount == res.min_price && total_coupons_second < res.coupons_used)){
            res.min_price = price_after_coupon_discount;
            res.coupons_used = total_coupons_second;
        }
    }

    return res;
}

九、C++算法源码

#include <bits/stdc++.h>
using namespace std;

// 定义一个结构体用于存储结果
struct Result {
    int min_price;      // 最低价格
    int coupons_used;   // 使用的优惠券数量
};

// 计算每个人的最低价格和使用的优惠券数量
Result calculate_min_price(int price, int full_reduction, int discounts, int coupons5){
    Result res;
    // 初始化最优价格为原价,不使用任何优惠券
    res.min_price = price;
    res.coupons_used =0;

    // 使用一张优惠券的情况
    // 1. 仅使用满减券
    if(full_reduction >0){
        // 计算可以使用的满减券数量
        int num_full_reduction = min(full_reduction, price /100);
        // 计算使用满减券后的价格
        int price_after_full = price -10 * num_full_reduction;
        // 更新最优价格和使用的优惠券数量
        if(price_after_full < res.min_price || (price_after_full == res.min_price && num_full_reduction < res.coupons_used)){
            res.min_price = price_after_full;
            res.coupons_used = num_full_reduction;
        }
    }

    // 2. 仅使用打折券
    if(discounts >0){
        // 计算使用打折券后的价格,并向下取整
        int price_after_discount = floor(price *0.92);
        // 使用一张打折券
        if(price_after_discount < res.min_price || (price_after_discount == res.min_price && 1 < res.coupons_used)){
            res.min_price = price_after_discount;
            res.coupons_used =1;
        }
    }

    // 3. 仅使用无门槛5元优惠券
    if(coupons5 >0){
        // 计算可以使用的5元优惠券数量
        int num_coupons = min(coupons5, price /5);
        // 计算使用5元优惠券后的价格
        int price_after_coupon = price -5 * num_coupons;
        // 更新最优价格和使用的优惠券数量
        if(price_after_coupon < res.min_price || (price_after_coupon == res.min_price && num_coupons < res.coupons_used)){
            res.min_price = price_after_coupon;
            res.coupons_used = num_coupons;
        }
    }

    // 使用两种优惠券的情况
    // 1. 满减券 + 打折券
    if(full_reduction >0 && discounts >0){
        // 先使用满减券,再使用打折券
        int num_full_reduction = min(full_reduction, price /100);
        int price_after_full = price -10 * num_full_reduction;
        int price_after_full_discount = floor(price_after_full *0.92);
        int total_coupons = num_full_reduction +1;
        if(price_after_full_discount < res.min_price || (price_after_full_discount == res.min_price && total_coupons < res.coupons_used)){
            res.min_price = price_after_full_discount;
            res.coupons_used = total_coupons;
        }

        // 先使用打折券,再使用满减券
        int price_after_discount = floor(price *0.92);
        int num_full_reduction_discount = min(full_reduction, price_after_discount /100);
        int price_after_discount_full = price_after_discount -10 * num_full_reduction_discount;
        int total_coupons_discount =1 + num_full_reduction_discount;
        if(price_after_discount_full < res.min_price || (price_after_discount_full == res.min_price && total_coupons_discount < res.coupons_used)){
            res.min_price = price_after_discount_full;
            res.coupons_used = total_coupons_discount;
        }
    }

    // 2. 满减券 + 无门槛5元优惠券
    if(full_reduction >0 && coupons5 >0){
        // 先使用满减券,再使用5元优惠券
        int num_full_reduction = min(full_reduction, price /100);
        int price_after_full = price -10 * num_full_reduction;
        int num_coupons = min(coupons5, price_after_full /5);
        int price_after_full_coupon = price_after_full -5 * num_coupons;
        int total_coupons_full = num_full_reduction + num_coupons;
        if(price_after_full_coupon < res.min_price || (price_after_full_coupon == res.min_price && total_coupons_full < res.coupons_used)){
            res.min_price = price_after_full_coupon;
            res.coupons_used = total_coupons_full;
        }

        // 先使用5元优惠券,再使用满减券
        int num_coupons_first = min(coupons5, price /5);
        int price_after_coupon_first = price -5 * num_coupons_first;
        int num_full_reduction_second = min(full_reduction, price_after_coupon_first /100);
        int price_after_coupon_full = price_after_coupon_first -10 * num_full_reduction_second;
        int total_coupons_second = num_coupons_first + num_full_reduction_second;
        if(price_after_coupon_full < res.min_price || (price_after_coupon_full == res.min_price && total_coupons_second < res.coupons_used)){
            res.min_price = price_after_coupon_full;
            res.coupons_used = total_coupons_second;
        }
    }

    // 3. 打折券 + 无门槛5元优惠券
    if(discounts >0 && coupons5 >0){
        // 先使用打折券,再使用5元优惠券
        int price_after_discount = floor(price *0.92);
        int num_coupons = min(coupons5, price_after_discount /5);
        int price_after_discount_coupon = price_after_discount -5 * num_coupons;
        int total_coupons_discount =1 + num_coupons;
        if(price_after_discount_coupon < res.min_price || (price_after_discount_coupon == res.min_price && total_coupons_discount < res.coupons_used)){
            res.min_price = price_after_discount_coupon;
            res.coupons_used = total_coupons_discount;
        }

        // 先使用5元优惠券,再使用打折券
        int num_coupons_first = min(coupons5, price /5);
        int price_after_coupon_first = price -5 * num_coupons_first;
        int price_after_coupon_discount = floor(price_after_coupon_first *0.92);
        int total_coupons_second = num_coupons_first +1;
        if(price_after_coupon_discount < res.min_price || (price_after_coupon_discount == res.min_price && total_coupons_second < res.coupons_used)){
            res.min_price = price_after_coupon_discount;
            res.coupons_used = total_coupons_second;
        }
    }

    return res;
}


🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)

🏆本文收录于,华为OD机试真题(Python/JS/C/C++)

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哪 吒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值