华为OD机试:16 网上商城优惠活动

package a_od_test;

import java.util.HashMap;
import java.util.Scanner;

/*
网上商城优惠活动(一)
时间限制:1s空间限制:50MB限定语言:不限
题目描述:
【背景】
某网上商城举办优惠活动,发布了满减、打折、无门槛3种优惠券Q,分别为:
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向下取整Q)元,不同使用顺序的优惠价格不同,以最优惠价格为准。在一
次购物中,同一类型优惠券使用多张时必须一次性使用,不能分多次拆开穿插使用(不允许先使用1张满减券,再用打折券,再使用一张满减券)。
【问题】
情设计实现一种解决方法,帮助购物者以最少的优惠券获得最优的优惠价格。优惠后价格越低越好,同等优惠价格,使用的优惠券越少越好,可以允许某次购物不使用优惠券。
【约定】
优惠活动每人只能参加一次,每个人的优惠券种类和数量是一样的。
输入描述:
第一行:每个人拥有的优惠券数量(数量取值范围为[0,10]),按满减、打折、无门槛的顺序输入。
第二行:表示购物的人数n(1<=n<=10000)。
最后行:每一行表示某个人优惠前的购物总价格(价格取值范围(0,1000],都为整数)约定:输入都是符合题目设定的要求的。
输出描述:
每行输出每个人每次购物优惠后的最低价格以及使用的优惠券总数量,每行的输出顺序和输入的顺序保持一致。补充说明:
1.优惠券数量都为整数,取值范围为[0,10]。
2.购物人数为整数,取值范围为[1,10000]。
3.优惠券的购物总价为整数,取值范围为(0,1000]。
4.优惠后价格如果是小数,则向下取整,输出都为整数。
示例1
输入:
325
3
100
200
400

输出:
65
155
338

说明:
【输入说明】
第一行:3种优惠券数量分别为满减券3张,打折券2张,无门槛5张第二行:总共3个人购物
第三行:第一个人购物优惠前价格为100元第四行:第二个人购物优惠前价格为200元第五行:第三个人购物优惠前价格为400元
【输出说明】
输入3个人,输出3行结果,同输入的顺序,对应每个人的优惠结果,如下:
第一行:先使用1张满减券优惠到90元,再使用5张无门槛券优惠25元,最终价格是65元,总共使用6张优惠券
第二行:先使用2张满减券优惠到180元,再使用5张无门槛券优惠25元,最终价格是155元,总共使用7张优惠券
第三行:先使用1张92折券优惠到368元,再使用3张满减券优惠30元,最终价格是338元,总共使用4张优惠券
解题思路:
主要分四种情况:先满减再打折,先打折再满减,先满减再无门槛,先打折再无门槛
注:因为无门槛是直接减,所以不能在满减和打折前面。

 */
public class Main16 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String[] split = sc.nextLine().split("");
        //定义满减,打折,无门槛劵张数
        int manjian = Integer.parseInt(split[0]);
        int dazhe = Integer.parseInt(split[1]);
        int wumenkan = Integer.parseInt(split[2]);
        int num = Integer.parseInt(sc.nextLine());
        for (int i = 0; i < num; i++) {
            //定义优惠前总价格
            int amount = Integer.parseInt(sc.nextLine());
            //主要分四种情况:先满减再打折,先打折再满减,先满减再无门槛,先打折再无门槛
            //使用map来存每种情况对应的优惠后金额
            HashMap<String, Double> map = new HashMap<>();
            int newManjian = Math.min((int) amount / 100, manjian);
            //先满减再打折
            double result = mj(amount, newManjian) * 0.92;
            map.put("mjdz", result);
            //先打折再满减
            //满减张数取决于优惠前金额
            double mjAmount = amount * 0.92;
            int mjManjian = (int) mjAmount / 100;
            result = mj(mjAmount, mjManjian);

            map.put("dzmj", result);
            //先满减再无门槛
            result = mj(amount, newManjian) - wumenkan * 5;
            map.put("mjwmk", result);
            //先打折再无门槛
            result = (amount * 0.92) - wumenkan * 5;
            map.put("dzwmk", result);

            double afterAmount = Integer.MAX_VALUE;
            for (double after : map.values()) {
                afterAmount = Math.min(afterAmount, after);
            }

            System.out.println((int) afterAmount);
        }

    }

    public static double mj(double amount, int newManjian) {
        for (int i = 0; i < newManjian; i++) {
            if (amount >= 100) {
                amount = amount - 10;
            } else {
                break;
            }
        }
        return amount;
    }
}


  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值