PAT乙级1020,附AC代码和详细题目解析,提供一种不会超时的方法

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);
    }
}

猜你喜欢

转载自blog.csdn.net/CSDN_Lrcx/article/details/116139239