华硕编程竞赛11月JAVA专场 F题购买弹簧 题解

简介: 华硕编程竞赛11月JAVA专场 F题购买弹簧 题解

题目链接:题目链接

题面:

小王在体验完 ”自由弹簧“ 后,非常开心,想再玩一次,但厂家确告诉他试用已结束,如还需体验就要付费购买。

小王没有办法,只好拿出自己的零花钱,打算再购买一个 ”自由弹簧“,小王的零钱罐里都是一块、五块和十块的硬币,为了优化零钱罐的存储空间,小王打算使用尽可能多的硬币去购买 ”自由弹簧“。

假设 ”自由弹簧“ 的价格为 N 元,小王的零钱罐中分别含有 A 张一元硬币, B 张五元硬币, C 张十元硬币,其中 NABC都是小于100000的正整数。

小王想知道,如何支付 ”自由弹簧“ 的款项,才能让自己用掉尽可能多的硬币量?

该挑战输入 NABC 四个正整数,要求输出 o1(一元硬币的消耗量)、o5(五元硬币的消耗量)、o10(十元硬币的消耗量),若无法购买,则输出 oh my god

本次挑战需要你至少了解一些 Java 中整数的基本运算,了解基本的贪心思想。

知识点

  • 整数的基本运算
  • Java整数运算
  • 基础贪心思想

初始代码

public class CMain {
    public static String doWork(int v,int num1,int num5,int num10) {
        //代码编辑区 开始
        return "oh my god";
        //代码编辑区 结尾
    }
    public static void main(String[] args) {
        //测试用例
        System.out.printf((Objects.equals("oh my god",doWork(6653,226,72,352)) ? "【√正确】" : "【X错误】") + "弹簧价格%d,①元硬币%d个,⑤元硬币%d个,⑩元硬币%d个,购买方案:%s\n",6653,226,72,352,doWork(6653,226,72,352));
        System.out.printf((Objects.equals("3 115 0",doWork(578, 5,127, 951)) ? "【√正确】" : "【X错误】") + "弹簧价格%d,①元硬币%d个,⑤元硬币%d个,⑩元硬币%d个,购买方案:%s\n",578,5,127,951,doWork(578, 5,127, 951));
        System.out.printf((Objects.equals("66663 24445 0",doWork(188888, 66666,77777, 88888)) ? "【√正确】" : "【X错误】") + "弹簧价格%d,①元硬币%d个,⑤元硬币%d个,⑩元硬币%d个,购买方案:%s\n",188888,66666,77777,88888,doWork(188888, 66666,77777, 88888));
    }
}

样例说明

输入 NABC 四个正整数,要求输出 o1(一元硬币的消耗量)、o5(五元硬币的消耗量)、o10(十元硬币的消耗量),若无法购买,则输出 oh my god

如弹簧价格为 578,一元硬币有 5 个,五元硬币有 127 个,十元硬币为 951 个,则小王可以消耗 3 个一元硬币、115 个五元硬币、0 个十元硬币购买弹簧,最终输出 3 115 0

如弹簧价格为 6653,一元硬币有 226 个,五元硬币有 72 个,十元硬币为 352 个,小王不能购买弹簧,输出 oh my god

题解

基础贪心题。先判断所有的硬币金额是否大于弹簧的价格,若不到弹簧的价格,则输出 oh my god

若到弹簧的价格,则优先使用一元硬币,寻找是否可以完成购买。

若无法购买,则使用反向贪心的思想,弹簧总钱减去硬币价格这个值,让用到的硬币个数尽可能少,也就等价于弹簧价格用到的硬币个数尽可能多

参考代码如下:

import java.util.Objects;
public class CAns {
    public static String doWork(int v,int num1,int num5,int num10) {
        // 代码编辑区 开始
        int c1 = 0, c5 = 0, c10 = 0;
        // 所有硬币加起来都小于价格
        if(num1 + num5 * 5+ num10 * 10 < v) {
            return "oh my god";
        }
        // 一元硬币可以满足价格
        if(num1 >= v) {
            c1 = v;
            return c1 + " " + c5 + " " + c10;
        }
        // 使用反向贪心的思想,弹簧总钱减去硬币价格这个值,让用到的硬币个数尽可能少,也就等价于弹簧价格用到的硬币个数尽可能多
        int sum = num1 + num5 * 5 + num10 * 10 - v;
        // 每次都选择面值最大的,这样钱的个数就最少
        int x = sum / 10;
        if(x > num10) {
            sum = sum - 10 * num10;
            x = 0;
        } else {
            sum = sum -10 * x;
            x = num10 - x;
        }
        int y= sum / 5;
        if(y > num5) {
            sum = sum - 5 * num5;
            y = 0;
        } else {
            sum = sum - y * 5;
            y= num5 - y;
        }
        int flag = 1;
        int z = sum;
        // 总价还小于价格,买不了
        if(z > num1) {
            flag=0;
        } else {
            sum = sum - z;
            z = num1 - z;
        }
        if(flag == 0) {
            return "oh my god";
        }
        return z + " " + y + " " + x;
    }
    public static void main(String[] args) {
        //测试用例
        System.out.printf((Objects.equals("oh my god",doWork(6653,226,72,352)) ? "【√正确】" : "【X错误】") + "弹簧价格%d,①元硬币%d个,⑤元硬币%d个,⑩元硬币%d个,购买方案:%s\n",6653,226,72,352,doWork(6653,226,72,352));
        System.out.printf((Objects.equals("3 115 0",doWork(578, 5,127, 951)) ? "【√正确】" : "【X错误】") + "弹簧价格%d,①元硬币%d个,⑤元硬币%d个,⑩元硬币%d个,购买方案:%s\n",578,5,127,951,doWork(578, 5,127, 951));
        System.out.printf((Objects.equals("66663 24445 0",doWork(188888, 66666,77777, 88888)) ? "【√正确】" : "【X错误】") + "弹簧价格%d,①元硬币%d个,⑤元硬币%d个,⑩元硬币%d个,购买方案:%s\n",188888,66666,77777,88888,doWork(188888, 66666,77777, 88888));
    }
}

总结

要 AC 本题,必须学会基础贪心的算法,使用反向贪心的思想,弹簧总钱减去硬币价格这个值,让用到的硬币个数尽可能少,也就等价于弹簧价格用到的硬币个数尽可能多,最终通过本题。


相关文章
|
1天前
|
Java
深入理解Java并发编程:线程池的应用与优化
【5月更文挑战第18天】本文将深入探讨Java并发编程中的重要概念——线程池。我们将了解线程池的基本概念,应用场景,以及如何优化线程池的性能。通过实例分析,我们将看到线程池如何提高系统性能,减少资源消耗,并提高系统的响应速度。
11 5
|
1天前
|
消息中间件 安全 Java
理解Java中的多线程编程
【5月更文挑战第18天】本文介绍了Java中的多线程编程,包括线程和多线程的基本概念。Java通过继承Thread类或实现Runnable接口来创建线程,此外还支持使用线程池(如ExecutorService和Executors)进行更高效的管理。多线程编程需要注意线程安全、性能优化和线程间通信,以避免数据竞争、死锁等问题,并确保程序高效运行。
|
1天前
|
安全 Java 容器
深入理解Java并发编程:线程安全与性能优化
【5月更文挑战第18天】随着多核处理器的普及,并发编程变得越来越重要。Java提供了丰富的并发编程工具,如synchronized关键字、显式锁Lock、原子类、并发容器等。本文将深入探讨Java并发编程的核心概念,包括线程安全、死锁、资源竞争等,并分享一些性能优化的技巧。
|
2天前
|
安全 Java 开发者
Java中的多线程编程:理解与实践
【5月更文挑战第18天】在现代软件开发中,多线程编程是提高程序性能和响应速度的重要手段。Java作为一种广泛使用的编程语言,其内置的多线程支持使得开发者能够轻松地实现并行处理。本文将深入探讨Java多线程的基本概念、实现方式以及常见的并发问题,并通过实例代码演示如何高效地使用多线程技术。通过阅读本文,读者将对Java多线程编程有一个全面的认识,并能够在实际开发中灵活运用。
|
2天前
|
Java 编译器
Java并发编程中的锁优化策略
【5月更文挑战第18天】在Java并发编程中,锁是一种常用的同步机制,用于保护共享资源的访问。然而,不当的锁使用可能导致性能问题和死锁风险。本文将探讨Java中锁的优化策略,包括锁粗化、锁消除、锁分离和读写锁等技术,以提高并发程序的性能和可靠性。
|
2天前
|
Java 编译器
Java 并发编程中的锁优化策略
【5月更文挑战第17天】在 Java 并发编程中,锁是一种常见的同步机制,用于保护共享资源的访问。然而,不当使用锁可能导致性能问题和死锁风险。本文将探讨 Java 中的锁优化策略,包括锁粗化、锁消除、锁降级以及读写锁等技术,以提高并发程序的性能和可靠性。
|
3天前
|
Java 编译器
Java并发编程中的锁优化策略
【5月更文挑战第17天】在Java并发编程中,锁是一种常见的同步机制,用于保护共享资源。然而,使用不当的锁可能导致性能下降和死锁等问题。本文将探讨Java中锁的优化策略,包括锁粗化、锁消除、锁排序等方法,以提高程序的性能和可靠性。
|
3天前
|
存储 关系型数据库 MySQL
《MySQL 入门教程》第 05 篇 账户和权限,Java高并发编程详解深入理解pdf
《MySQL 入门教程》第 05 篇 账户和权限,Java高并发编程详解深入理解pdf
|
3天前
|
NoSQL Dubbo Java
StringBoot编程式事务与声明式事务java工程师面试突击第一季
StringBoot编程式事务与声明式事务java工程师面试突击第一季
|
4天前
|
安全 Java 开发者
深入理解Java并发编程:线程安全与性能优化
【5月更文挑战第15天】本文将深入探讨Java并发编程的核心概念,包括线程安全和性能优化。我们将通过实例分析,理解线程安全的重要性,并学习如何通过各种技术和策略来实现它。同时,我们也将探讨如何在保证线程安全的同时,提高程序的性能。