模拟商场优惠打折,有三种优惠券可以用,满减券、打折券和无门槛券。
满减券:满100减10,满200减20,满300减30,满400减40,以此类推不限制使用;
打折券:固定折扣92折,且打折之后向下取整,每次购物只能用1次;
无门槛券:一张券减5元,没有使用限制。
每个人结账使用优惠券时有以下限制:
每人每次只能用两种优惠券,并且同一种优惠券必须一次用完,不能跟别的穿插使用(比如用一张满减,再用一张打折,再用一张满减,这种顺序不行)。
求不同使用顺序下每个人用完券之后得到的最低价格和对应使用优惠券的总数;如果两种顺序得到的价格一样低,就取使用优惠券数量较少的那个。
输入描述:
第一行三个数字m,n.k,分别表示每个人可以使用的满减券、打折券和无门槛券的数量:
第二行一个数字x表示有几个人购物:
后面x行数字,依次表示是这几个人打折之前的商品总价
输出描述
输出每个人使用券之后的最低价格和对应使用优惠券的数量
Java实现:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class OdAb5 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int m = scanner.nextInt();
int n = scanner.nextInt();
int k = scanner.nextInt();
int x = scanner.nextInt();
List<Integer> prices = new ArrayList<>();
for (int i = 0; i < x; i++) {
prices.add(scanner.nextInt());
}
for (int price : prices) {
List<int[]> ans = new ArrayList<>();
int[] resM = fullSubtraction(price, m); // 先满减
int[] resMN_N = discount(resM[0], n); // 满减后打折
ans.add(new int[]{resMN_N[0], m + n - (resM[1] + resMN_N[1])}); // m + n 是满减后打折方式的总券数量, resM[1] + resMN_N[1] 是满减券剩余数+打折券剩余数
int[] resMK_K = thresholdFree(resM[0], k); // 满减后无门槛
ans.add(new int[]{resMK_K[0], m + k - (resM[1] + resMK_K[1])});
int[] resN = discount(price, n); // 先打折
int[] resNM_M = fullSubtraction(resN[0], m); // 打折后满减
ans.add(new int[]{resNM_M[0], n + m - (resN[1] + resNM_M[1])});
int[] resNK_K = thresholdFree(resN[0], k); // 打折后无门槛
ans.add(new int[]{resNK_K[0], n + k - (resN[1] + resNK_K[1])});
ans.sort((a, b) -> {
if (a[0] != b[0]) {
return Integer.compare(a[0], b[0]); // 优先按剩余总价升序
} else {
return Integer.compare(a[1], b[1]); // 如果剩余总价相同,则再按“使用掉的券数量”升序
}
});
System.out.println(ans.get(0)[0] + " " + ans.get(0)[1]);
}
}
private static int[] fullSubtraction(int price, int m) {
while (price >= 100 && m > 0) {
price -= price / 100 * 10;
m--;
}
return new int[]{price, m};
}
private static int[] discount(int price, int n) {
if (n >= 1) {
price = (int) (price * 0.92);
n--;
}
return new int[]{price, n};
}
private static int[] thresholdFree(int price, int k) {
while (price > 0 && k > 0) {
price -= 5;
price = Math.max(price, 0); // 无门槛券过多会导致优惠后总价小于0,此时我们应该避免
k--;
}
return new int[]{price, k};
}
}