whenever

  • Home

  • Tags21

  • Categories6

  • Archives122

  • About

PAT乙级1020 || 月饼(详解,C/C++示例,测试点分析)

Posted on 2019-08-18 In PAT

月饼

题目描述

月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不同风味的月饼。现给定所有种类月饼的库存量、总售价、以及市场的最大需求量,请你计算可以获得的最大收益是多少。
注意:销售时允许取出一部分库存。样例给出的情形是这样的:假如我们有 3 种月饼,其库存量分别为 18、15、10 万吨,总售价分别为 75、72、45 亿元。如果市场的最大需求量只有 20 万吨,那么我们最大收益策略应该是卖出全部 15 万吨第 2 种月饼、以及 5 万吨第 3 种月饼,获得 72 + 45/2 = 94.5(亿元)。

输入格式

每个输入包含一个测试用例。每个测试用例先给出一个不超过 1000 的正整数 N 表示月饼的种类数、以及不超过 500(以万吨为单位)的正整数 D 表示市场最大需求量。随后一行给出 N 个正数表示每种月饼的库存量(以万吨为单位);最后一行给出 N 个正数表示每种月饼的总售价(以亿元为单位)。数字间以空格分隔。

输出格式

对每组测试用例,在一行中输出最大收益,以亿元为单位并精确到小数点后 2 位。

输入样例

1
2
3
3 20
18 15 10
75 72 45

输出样例

1
94.50

问题解决

解题思想

为了利用每种月饼的单价对月饼进行排序,我把每种月饼的清单定义为结构体类型,利用sort()函数可非常方便地对每种月饼按单价排序;因为要按照降序进行排序,因此需定义排序规则函数cmp();最大收益策略应是:逐次选择单价由高到低的月饼直到需求量得到满足为止。本题还应注意以下两个方面:

  • 题中说明了库存量,总售价都是正数,故应定义为实型

  • 若最大需求量大于所有月饼的总库存量,最大收益策略应该是卖出所有的月饼。

第二个方面容易忽略,若将代码中最后计算收益的while循环的条件改为如下:

1
while((d - ca_list[i].inv_coun) > 0))

提交时将会有一个测试点不通过(段错误),因为当需求量大于所有月饼的总库存量,i将累加到大于n甚至大于MAXN,从而导致错误或数组下标越界。加上i < n这个条件后在退出循环时还需要用if语句检查一下是否是由于i >= n而退出的循环(若是则需求量大于所有月饼的总库存量),若是,yield就不能再加上剩余的需求量乘上当前种类月饼的单价了。

知识拓展

在OJ上训练时,建议大家遇到实型数据就定义成double型,尽量不要定义为float型。在提交程序后评测出错,然后将float改为double后才得以AC时应该会有这样的“领悟”。

代码示例(C/C++)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <cstdio>
#include <algorithm>//使用sort()函数须加上此句
#define MAXN 1001
using namespace std;
//定义存货清单结构体类型
struct cargo_list
{
//库存量,总售价应定义为实型
double inv_coun;//库存量
double total_pri;//总售价
double unit_pri;//单价(单位:亿元/万吨)
}ca_list[MAXN];
//定义sort()函数的比较规则函数cmp()
bool cmp(cargo_list a,cargo_list b)
{
return a.unit_pri > b.unit_pri;
}
int main()
{
int n,d;
scanf("%d%d",&n,&d);
for(int i = 0; i < n; i++){
scanf("%lf",&ca_list[i].inv_coun);//输入库存量
}
for(int i = 0; i < n; i++){
scanf("%lf",&ca_list[i].total_pri);//输入总售价
ca_list[i].unit_pri = ca_list[i].total_pri / ca_list[i].inv_coun;//计算单价
}
sort(ca_list,ca_list + n,cmp);//按单价进行降序排序
int i = 0;
double yield = 0;//收益
while(((d - ca_list[i].inv_coun) > 0)&&(i < n)){
yield += ca_list[i].total_pri;//累加收益
d -= ca_list[i].inv_coun;//更新需求量
i++;
}//若更新后的需求量大于当前种类月饼的库存量则继续循环否则退出
if(i < n){
yield += d * ca_list[i].unit_pri;
}//若因(d - ca_list[i].inv_coun) <= 0退出循环,
//收益还需加上剩余的需求量乘上当前种类月饼的单价
printf("%.2lf",yield);
return 0;
}

题目来源:PAT乙级1020
作者:CHEN, Yue
单位:浙江大学

稀罕作者
Mengzhao Wang WeChat Pay

WeChat Pay

Mengzhao Wang Alipay

Alipay

# C/C++ # PAT # 编程
PAT乙级1019 || 数字黑洞(详解,C/C++示例,测试点分析)
PAT乙级1021 || 个位数统计(详解,C/C++示例,测试点分析)
  • Table of Contents
  • Overview
Mengzhao Wang

Mengzhao Wang

Try? All the way !
122 posts
6 categories
21 tags
  1. 1. 月饼
    1. 1.1. 题目描述
    2. 1.2. 输入格式
    3. 1.3. 输出格式
    4. 1.4. 输入样例
    5. 1.5. 输出样例
    6. 1.6. 问题解决
      1. 1.6.1. 解题思想
      2. 1.6.2. 知识拓展
      3. 1.6.3. 代码示例(C/C++)
© 2021 Mengzhao Wang