PAT(Advanced) 1037 Magic Coupon 优先级队列 C++实现
题目链接
题目大意
给定优惠券面值数组和产品价格数组,数组中的值可正可负,使用面值为 N N N的优惠券购买价格为 M M M的产品可以得到 N × M N \times M N×M的返利,求可以得到的最大返利值并输出。
算法思路
优惠券面值和产品价格分别为正正、正负、负负、负正
的四种情况,能够增加返利的只有正正(整数越大,乘积越大)和负负(负数越小,乘积越大),采用C++ STL
中的优先级队列,最大堆分别存储优惠券面值和产品价格为正的值,最小堆分别存储优惠券面值和产品价格为负的值。优惠券面值最大堆和产品价格最大堆依次同时弹出最大值相乘累加到结果,直到一个最大堆为空位置,优惠券面值最小堆和产品价格最小堆依次同时弹出最小值(负数)相乘累加到结果,直到一个最小堆为空位置;输出最后的结果。
AC代码
/*
author : eclipse
email : [email protected]
time : Sun Jan 31 18:05:25 2021
*/
#include <bits/stdc++.h>
using namespace std;
int main(int argc, char const *argv[]) {
int N;
scanf("%d", &N);
priority_queue<int> positiveCoupons;
priority_queue<int, vector<int>, greater<int> > negativeCoupons;
priority_queue<int> positiveProducts;
priority_queue<int, vector<int>, greater<int> > negativeProducts;
for (int i = 0; i < N; i++) {
int coupon;
scanf("%d", &coupon);
if (coupon > 0) {
positiveCoupons.push(coupon);
} else if (coupon < 0) {
negativeCoupons.push(coupon);
}
}
scanf("%d", &N);
for (int i = 0; i < N; i++) {
int product;
scanf("%d", &product);
if (product > 0) {
positiveProducts.push(product);
} else if (product < 0) {
negativeProducts.push(product);
}
}
int ans = 0;
while (!positiveCoupons.empty() && !positiveProducts.empty()) {
ans += positiveCoupons.top() * positiveProducts.top();
positiveCoupons.pop();
positiveProducts.pop();
}
while (!negativeCoupons.empty() && !negativeProducts.empty()) {
ans += negativeCoupons.top() * negativeProducts.top();
negativeCoupons.pop();
negativeProducts.pop();
}
printf("%d", ans);
return 0;
}
样例输入
4
1 2 4 -1
4
7 6 -2 -3
样例输出
43
鸣谢
最后
- 由于博主水平有限,不免有疏漏之处,欢迎读者随时批评指正,以免造成不必要的误解!