1020 月饼 (25分)
月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不同风味的月饼。现给定所有种类月饼的库存量、总售价、以及市场的最大需求量,请你计算可以获得的最大收益是多少。
注意:销售时允许取出一部分库存。样例给出的情形是这样的:假如我们有 3 种月饼,其库存量分别为 18、15、10 万吨,总售价分别为 75、72、45 亿元。如果市场的最大需求量只有 20 万吨,那么我们最大收益策略应该是卖出全部 15 万吨第 2 种月饼、以及 5 万吨第 3 种月饼,获得 72 + 45/2 = 94.5(亿元)。
输入格式:
每个输入包含一个测试用例。每个测试用例先给出一个不超过 1000 的正整数N表示月饼的种类数、以及不超过 500(以万吨为单位)的正整数D表示市场最大需求量。随后一行给出N个正数表示每种月饼的库存量(以万吨为单位);最后一行给出N个正数表示每种月饼的总售价(以亿元为单位)。数字间以空格分隔。
输出格式:
对每组测试用例,在一行中输出最大收益,以亿元为单位并精确到小数点后 2 位。
输入样例:
3 20
18 15 10
75 72 45
输出样例:
94.50
题目解析:
今天这道题还是老样子,题目时间限制150ms,使用Scanner会超时,这里还是使用BufferedReader,这里推荐除非控制台录入信息特别简单(比如只有2个整数之类的),否则的话推荐BufferedReader,尤其是甲级时基本不使用Scanner.
方法:定义三个float类型数组kucun,price,singleprice,分别存储库存,价格,单价(为什么是float,因为题目说给出的数是正数,没有保证是正整数)。按照单价从高到底对单价进行排序(库存和价格的位置也要相应的变动,要保证在数组中这三个数据的一一对应)。然后定义整型变量totol,sumprice,分别存储总量、总价。然后循环判断直到totol达到D的数量。
AC代码:
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws Exception{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String s[]=br.readLine().split(" ");//录入第一行数据,包含月饼种类数和市场最大需求量
int N=Integer.parseInt(s[0]);//月饼种类数
int D=Integer.parseInt(s[1]);//市场最大需求量
String[] str1=br.readLine().split(" ");//录入的第二行数据
String[] str2=br.readLine().split(" ");//录入的第三行数据
float[] kucun=new float[N];//存放库存量
float[] price=new float[N];//存放价格
float singlePrice[]=new float[N];//存放单价
for(int i=0;i<N;i++){
//分别转换成float类型的数据存到数组,并求出单价
kucun[i]=Float.parseFloat(str1[i]);
price[i]=Float.parseFloat(str2[i]);
singlePrice[i]=price[i]/kucun[i];
}
/*从高到底对单价进行排序,库存和价格的位置也要相应变动
保证kuncun price singlePrice的位置一一对应,这里我采用
的排序方法是选择排序*/
for(int i=0;i<N-1;i++){
for(int j=i;j<N;j++){
if(singlePrice[i]<singlePrice[j]){
//变动单价
float temp=singlePrice[i];
singlePrice[i]=singlePrice[j];
singlePrice[j]=temp;
//变动价格
temp=price[i];
price[i]=price[j];
price[j]=temp;
//变动库存
temp=kucun[i];
kucun[i]=kucun[j];
kucun[j]=temp;
}
}
}
int totle=0;//存放库存量
float sumprice=0;//储存最高价格
for(int i=0;i<N;i++){
//for循环内部是整道题的核心
//D-totol,表示还差多少就够D了
//这个if表示相差的量比这个库存要大,价格和库存量直接加上去
if(D-totle>kucun[i]){
totle+=kucun[i];
sumprice+=price[i];
}else if(D-totle==kucun[i]){
//这个else if表示还差kucun[i]这么多就到D了,直接把价格加上来,退出循环就OK
sumprice+=price[i];
break;
}else{
//这里表示kucun[i]比差多少到D的量大,那么只取D-totol这么多量就到D了
sumprice+=singlePrice[i]*(D-totle);
break;
}
}
//输出最后的价格,保留小数点后两位
System.out.printf("%.2f",sumprice);
}
}