题目
FatMouse prepared M pounds of cat food, ready to trade with the cats guarding the warehouse containing his favorite food, JavaBean.
胖老鼠准备了M磅的猫粮,准备与守卫他最喜欢的食物JavaBean的仓库的猫进行交易。
胖老鼠准备了M磅的猫粮,准备与守卫他最喜欢的食物JavaBean的仓库的猫进行交易。
The warehouse has N rooms. The i-th room contains J[i] pounds of JavaBeans and requires F[i] pounds of cat food. FatMouse does not have to trade for all the JavaBeans in the room, instead, he may get J[i]* a% pounds of JavaBeans if he pays F[i]* a% pounds of cat food. Here a is a real number. Now he is assigning this homework to you: tell him the maximum amount of JavaBeans he can obtain.
仓库有N个房间。第 i 个房间包含 J[i] 磅的 JavaBeans,需要 F[i] 磅的猫粮。FatMouse 不必交易房间里的所有 JavaBeans,相反,如果他支付 F[i]* a% 磅的猫粮,他可能会得到 J[i]* a% 磅的 JavaBeans。这里 a 是一个实数。现在他正在给你布置这个作业:告诉他他能获得的最大 JavaBeans 数量。
Input
The input consists of multiple test cases. Each test case begins with a line containing two non-negative integers M and N. Then N lines follow, each contains two non-negative integers J[i] and F[i] respectively. The last test case is followed by two -1's. All integers are not greater than 1000.
输入由多个测试用例组成。每个测试用例都以包含两个非负整数 M 和 N 的行开头。然后是 N 行,每行分别包含两个非负整数 J[i] 和 F[i]。最后一个测试用例后面跟着两个 -1。所有整数都不大于 1000。
输入由多个测试用例组成。每个测试用例都以包含两个非负整数 M 和 N 的行开头。然后是 N 行,每行分别包含两个非负整数 J[i] 和 F[i]。最后一个测试用例后面跟着两个 -1。所有整数都不大于 1000。
Output
For each test case, print in a single line a real number accurate up to 3 decimal places, which is the maximum amount of JavaBeans that FatMouse can obtain.
对于每个测试用例,在一行中打印一个精确到小数点后 3 位的实数,这是 FatMouse 可以获得的最大 JavaBean 数量。
对于每个测试用例,在一行中打印一个精确到小数点后 3 位的实数,这是 FatMouse 可以获得的最大 JavaBean 数量。
Sample
Inputcopy | Outputcopy |
---|---|
5 3
7 2
4 3
5 2
20 3
25 18
24 15
15 10
-1 -1
| 13.333
31.500
|
思路
为了尽可能换取多的JavaBean,我们要尽可能多的去兑换性价比较高的JavaBean,因此可以使用我们所学过的multimap容器,这样可以为我们防止有相同性价比的商店,同时可以根据性价比的倒数正序排列,也就是按性价比越高越在前,猫粮够的话就全换完,不够了就尽可能换,同时停止,具体代码如以下实现。
代码实现
#include <iostream>
#include <map>
using namespace std;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);//关闭同步流
double m, n;
double x, y, sum;
while (cin >> m >> n, m != -1) {
sum = 0;
multimap<double, double>mp;//采用multimap用于排序和防止同性价比情况
while (n--) {
cin >> x >> y; //y是换的,key越小,越优先换
if (x == 0)continue;//如果一个也换不到,那么直接跳过
if (y == 0)//如果0个就能换,那么就直接加上,肯定要换
sum += x;
else
mp.insert(pair<double, double>(y / x, y));//其他的就按性价比倒数排序
}
if (m == 0)sum = sum;//如果0猫粮,那么sum就是该值(防止有0猫粮情况)
else {
for (auto it = mp.begin(); it != mp.end(); it++) {
if (m - (it->second) < 0) {//如果猫粮不够减了
sum += (m / (it->second)) * (it->second / it->first);//那么取最大百分比
break;//结束
} else {
sum += it->second / it->first;//如果够减,那么就全部算上
m -= it->second;
}
}
}
printf("%.3lf\n", sum);//保留三位小数
}
}
尾声
本题带我们熟悉了multimap的使用,同时本题对0的处理也是相当关键,如果想到了排序和对0的处理,那么对于你来说这道题就易如反掌了。
总结
本题为我们提供了新的思路,同时熟悉了multimap的如果觉得笔者写的还不错的话,那么留下您的点赞收藏和关注哦~