ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

PTA---贪心算法

2021-10-21 12:31:27  阅读:190  来源: 互联网

标签:Scanner 月饼 int double PTA --- ++ numValRate 贪心


文章目录

7-1 装箱问题

在这里插入图片描述


import java.util.Scanner;

public class Program1 {
    public static void main(String[] args) {
        int N;
        Scanner in = new Scanner(System.in);
        N = in.nextInt();
        int []things = new int[N];
        //最多有N个箱子
        int []box = new int[N];
        //记录最大所需箱子数
        int maxBox = 0;
        //对每个物品进行顺序装箱
        for(int i = 0;i < N;i++){
            //物品输入
            things[i] = in.nextInt();
            //存箱模拟
            int index = 0;
            while (box[index] + things[i] > 100 ){
                index++;
            }
            box[index] += things[i];
            System.out.println(things[i] + " " + (index + 1));
            if(maxBox < index + 1){
                maxBox = index + 1;
            }

        }
        System.out.println(maxBox);

    }
}

7-2 月饼

7-2 月饼 (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 位
在这里插入图片描述
这题对java超级不友好,使用java自带的快排容易超时,而且有些还不支持。。。。。无语

Java参考代码:


import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

public class Program2 {
    /**
     * 解题思路:根据月饼数量和售价比值进行选择,每次选择比值最小的总收益最大
     *
     */
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int N = in.nextInt();       //月饼种类
        int D = in.nextInt();       //总库存
        //二维数组分别存储月饼库存,总售价
        double [][]numValRate = new double[N][2];
        for(int i = 0;i < N;i++){
            numValRate[i][0] = in.nextDouble();
        }
        for(int i = 0;i < N;i++){
            numValRate[i][1] = in.nextDouble();
        }
        //根据比值进行从小到大排序
        // 下面这个排序在PTA上会超时原因不明
        //Arrays.sort(numValRate, Comparator.comparingDouble(o -> ((double) o[0] / o[1])));
        Arrays.sort(numValRate, new Comparator<double[]>() {
            @Override
            public int compare(double[] o1, double[] o2) {
                if(o1[0] / o1[1] - o2[0] / o2[1] >= 0){
                    return 1;
                }else {
                    return -1;
                }
            }
        });
        double sumVal = 0;         //总收益
        int i = 0;
        while (!(D <= 0 || i >= N)){
            if(D >= numValRate[i][0]){
                D -= numValRate[i][0];
                sumVal += numValRate[i][1];
            }else {
                sumVal += ((double)D / numValRate[i][0]) * numValRate[i][1];
                D = 0;
            }
            i++;
        }
        System.out.printf("%.2f\n",sumVal);
    }
}

可提交的C代码:


//贪心月饼问题
#include <stdio.h>
#include <stdlib.h>

int cmp(const void *_a, const void *_b) {
    double *a = (double *) (_a);
    double *b = (double *) (_b);
    if (a[0] / a[1] - b[0] / b[1] >= 0) {
        return 1;
    } else {
        return -1;
    }
}

int main() {
    /**
     * 解题思路:根据月饼数量和售价比值进行选择,每次选择比值最小的总收益最大
     *
     */

    int N;       //月饼种类
    scanf("%d", &N);
    int D;       //总库存
    scanf("%d", &D);
    //二维数组分别存储月饼库存,总售价
    double numValRate[N][2];
    for (int i = 0; i < N; i++) {
        scanf("%lf", &numValRate[i][0]);
    }
    for (int i = 0; i < N; i++) {
        scanf("%lf", &numValRate[i][1]);
    }
    qsort(numValRate, sizeof(numValRate) / sizeof(numValRate[0]), sizeof(numValRate[0]), cmp);
    double sumVal = 0;         //总收益
    int i = 0;
    while (!(D <= 0 || i >= N)) {
        if (D >= numValRate[i][0]) {
            D -= numValRate[i][0];
            sumVal += numValRate[i][1];
        } else {
            sumVal += ((double) D / numValRate[i][0]) * numValRate[i][1];
            D = 0;
        }
        i++;
    }

    printf("%.2f\n", sumVal);
}

##7-3 汽车加油问题 (25 分)
题目来源:王晓东《算法设计与分析》

一辆汽车加满油后可行驶 n公里。旅途中有若干个加油站。设计一个有效算法,指出应 在哪些加油站停靠加油,使沿途加油次数最少。

输入格式:
第一行有 2 个正整数n和 k(k<=1000 ),表示汽车加满油后可行驶n公里,且旅途中有 k个加油站。 第二行有 k+1 个整数,表示第 k 个加油站与第k-1 个加油站之间的距离。 第 0 个加油站表示出发地,汽车已加满油。 第 k+1 个加油站表示目的地。

输出格式:
输出最少加油次数。如果无法到达目的地,则输出“No Solution!”。


import java.util.Scanner;

public class Program3 {
    //贪心算法:汽油加油问题
    //思路:只要剩余的油能够到达下一站就不停车,否则停车加油
    static final String NoSolution = "No Solution!";
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();       //油箱总量
        int k = in.nextInt();       //目的地数量
        int []pos = new int[k + 1]; //加油站信息
        for(int i = 0;i < k + 1;i++){
            pos[i] = in.nextInt();
        }
        int minTime = 0;
        int fuelTank = n;
        for(int i = 0;i < k + 1;i++){
            //油量充足
            if(pos[i] <= fuelTank){
                fuelTank -= pos[i];
            }else if(pos[i] > fuelTank && fuelTank == n){
                //满油箱量不足到达
                minTime = -1;
                break;
            }else {
                //加满油
                fuelTank = n;
                fuelTank -= pos[i];
                minTime++;
            }
        }
        if(minTime >= 0){
            System.out.println(minTime);
        }else {
            System.out.println(NoSolution);
        }
    }
}
/*
7 7
1 2 3 4 5 1 6 6

 */

7-4 活动选择问题

在这里插入图片描述


import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

public class Program4 {
    //贪心:获得选择问题
    //思路:根据活动最快结束时间进行选择,开始时间为上一个活动的结束时间
    //初始开始时间为0
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int [][]active = new int[n][2];
        for(int i = 0;i < n;i++){
            active[i][0] = in.nextInt();
            active[i][1] = in.nextInt();
        }
        //排序,根据最快结束时间进行排序,从小到大排序
        Arrays.sort(active, new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                return o1[1] - o2[1];
            }
        });
        int times = 0;      //最多活动次数
        int startTime = 0;
        int index = 0;
        while (index < n){
            if(startTime <= active[index][0]){
                times++;
                startTime = active[index][1];
            }
            index++;
        }
        System.out.println(times);

    }
}
/*
11
3 5
1 4
12 14
8 12
0 6
8 11
6 10
5 7
3 8
5 9
2 13

 */

标签:Scanner,月饼,int,double,PTA,---,++,numValRate,贪心
来源: https://blog.csdn.net/wr456wr/article/details/120883415

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有