2.2-11【1】魔法优惠劵(排序)
2.2-1问题描述
2.21-A[问题描述]
在火星上有个魔法商店,通过魔法优惠券。每个优惠券上印有一个整数面值K,表示若你在购买某商品使用这张优惠券,可以得到K倍该商品价值的回报。该商店还免费赠送一些有价值的商品,但如果你在领取免费赠品的时候使用面值为正的优惠券,则必须倒贴给商品K倍该商品价值的金额……但是不要紧,还有面值为负的优惠券可以用。
例如,给定一组优惠券,面值分别为1、2、4、-1;对应一组商品,价值为火星币7、6、-2、-3,其中负的价值表示该商品是免费赠品。我们可以将优惠券3(面值4)用在商品1(价值7)上,得到火星币28的回报。优惠券4(面值-1)用在商品4(价值-3)上,得到火星币3的回报。但是,如果一不小心把优惠券3(面值4)用到商品4(价值-3)上,你必须倒贴给商店火星币12个。同样,把优惠券4(面值-1)用到商品1(价值7)上,你必须倒贴给商店火星币7个。
规定每张优惠券和每件商品都只能最多被使用一次,求你可以得到的最大回报。
2.2.1-B[基本要求]
(1)输入说明:输入有两行。第一行首先给出优惠券的个数N,随后给出N个优惠券的整数面值。 第二行首先给出商品的个数M,随后给出M个商品的整数价值。N和M在[1,106]之间,所有的数据大小不超过230,数字间以空格分隔。
(2)输出说明:输出可以得到的最大回报。
2.2.2 算法思想
首先,从标准输入读入优惠券面值和商品价格,并排序。然后使用两个指针同时遍历数组,计算当前优惠券面值乘以商品价格并累加到最大利润中。最后输出最大利润。
2.2.3 源代码 [共75行]
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int N, M;
cin >> N; // 输入优惠券的面值数量
int ans[N];
for (int i = 0; i < N; i++)
{
cin >> ans[i]; // 依次输入每种优惠券的面值
}
cin >> M; // 输入商品价格数量
int products[M];
for (int i = 0; i < M; i++)
{
cin >> products[i]; // 依次输入每种商品的价格
}
// 对优惠券和商品进行排序,从小到大排列
sort(ans, ans + N);
sort(products, products + M);
long long max_profit = 0;
// 遍历正数部分
int i = N - 1, j = M - 1; // 从优惠券和商品数组的最后开始遍历
while (i >= 0 && j >= 0)
{
if (ans[i] > 0 && products[j] > 0) // 如果优惠券和商品均为正数
{
max_profit += (long long)ans[i] * products[j]; // 最大利润加上优惠券面值乘商品价格
i--; // 移动到下一个优惠券面值
j--; // 移动到下一个商品价格
}
else
{ // 如果优惠券和商品均不为正数,或者一方为零,则退出循环
break;
}
}
// 遍历负数部分
i = 0, j = 0; // 从优惠券和商品数组的开头开始遍历
while (i < N && j < M)
{
if (ans[i] < 0 && products[j] < 0) // 如果优惠券和商品均为负数
{
max_profit += (long long)ans[i] * products[j]; // 最大利润加上优惠券面值乘商品价格
i++; // 移动到下一个优惠券面值
j++; // 移动到下一个商品价格
}
else
{ // 如果优惠券和商品均不为负数,或者一方为零,则退出循环
break;
}
}
// 输出最大利润
cout << max_profit << endl;
return 0;
}
2.2.4 PTA测评结果
正确-25 / 25分(满分)。