题解 | #自动售货系统# #动态规划# 最折磨的一集

自动售货系统

https://www.nowcoder.com/practice/cd82dc8a4727404ca5d32fcb487c50bf

import sys
from dataclasses import dataclass
from typing import List


@dataclass
class Goods:
    name: str
    price: int
    quantity: int


coins = (1, 2, 5, 10)


class Machine:
    def __init__(self):
        self.goods: List[Goods] = [Goods(f"A{x}", x + 1, 0) for x in range(1, 5)] + [
            Goods("A5", 8, 0),
            Goods("A6", 6, 0),
        ]
        self.coin_box: List[int] = []
        self.balance: int = 0

    def init(self, goods_quantity: List[int], coins_qunatity: List[int]) -> str:
        for good, qty in zip(self.goods, goods_quantity):
            good.quantity = qty
        for index, qty in enumerate(coins_qunatity):
            self.coin_box += [coins[index]] * qty
        return "S001:Initialization is successful"

    def is_sold_out(self) -> bool:
        # 如果卖完就返回true
        return all(good.quantity == 0 for good in self.goods)

    def sum_of_one_two(self) -> int:
        return self.coin_box.count(1) + 2*self.coin_box.count(2)

    def insert_coin(self, amount: int) -> str:
        if amount not in {1, 2, 5, 10}:  # 不为指定面额
            return "E002:Denomination error"
        if self.sum_of_one_two() < amount:
            return "E003:Change is not enough, pay fail"
        if self.is_sold_out():  # 卖完
            return "E005:All the goods sold out"
        self.balance += amount
        self.coin_box.append(amount)
        return f"S002:Pay success,balance={self.balance}"

    def purchase(self, good: str) -> str:
        for x in self.goods:
            if x.name == good:
                if x.quantity == 0:  # 数量为0
                    return "E007:The goods sold out"
                if self.balance < x.price:  # 钱不够
                    return "E008:Lack of balance"
                # 购买商品成功后,自动售货机中对应商品数量减1,投币余额扣除本次购买商品的价格。
                x.quantity -= 1
                self.balance -= x.price
                return f"S003:Buy success,balance={self.balance}"
        return "E006:Goods does not exist"

    def return_cash(self) -> str:
        if self.balance == 0:
            return "E009:Work failure"
        # 按钱币总张数最少的原则进行退币
        # 如果因零钱不足导致不能退币,则尽最大可能退币

        tmp = [()] * (self.balance+1)
        self.coin_box = sorted(self.coin_box, reverse=True)
        for x in self.coin_box:
            for index, comb in enumerate(tmp):
                if comb == () and index != 0:
                    continue
                new_amount = index + x
                if new_amount > self.balance:
                    continue

                if tmp[new_amount] != ():
                    if len(tmp[new_amount]) > len(comb) + 1:
                        tmp[new_amount] = tuple(comb) + (x,)
                else:
                    tmp[new_amount] = tuple(comb) + (x,)
       
        for x in reversed(tmp):
            if x != ():
                # 从零钱中删除该组合
                # 清零balance
                
                for y in x:
                    self.coin_box.remove(y)
                self.balance = 0
                return self.return_coins_str(x)

    def return_goods_str(self):
        return "\n".join(f"{x.name} {x.price} {x.quantity}" for x in self.goods)

    def return_coins_str(self,coin):
        return '\n'.join(f"{x} yuan coin number={coin.count(x)}" for x in coins)

    def return_self_coins_str(self):
        return self.return_coins_str(self.coin_box)

def solve_cmd(cmd: str, machine: Machine):
    #分析解后的命令 例如 p 1
    content = cmd.split()
    result  = 'E010:Parameter error'
    if len(content) == 1 and content[0] == 'c':
        result = machine.return_cash()

    if content[0] == 'r':
        result = machine.init(list(map(int,content[1].split('-'))), list(map(int,content[2].split('-'))))

    if content[0]=='p':
        result = machine.insert_coin(int(content[1]))

    if content[0]=='b':
        result = machine.purchase(content[1])

    if content[0]=='q':
        if content[1] == '0':
            result = machine.return_goods_str()
        elif content[1] == '0':
            result = machine.return_goods_str()
            
    return result

machine = Machine()
command = input().split(';')
for x in command:
    if x:
        print(solve_cmd(x,machine))

需要用动态规划计算每个数值的最小可能组合,最好是逆序从最大的面值开始找起,为以防找不到组合,把动态规划的列表进行一个逆序输出。输出答案的时候不要忘记把余额清零,零钱也不要忘去除。

最折磨的苦力题目

全部评论

相关推荐

不会取名字的牛油:学历加大加粗,面试库库来
点赞 评论 收藏
分享
会飞的猿:我看你想进大厂,我给你总结一下学习路线吧,java语言方面常规八股要熟,那些java的集合,重点背hashmap八股吧,jvm类加载机制,运行时分区,垃圾回收算法,垃圾回收器CMS、G1这些,各种乐观锁悲观锁,线程安全,threadlocal这些。在进阶一些的比如jvm参数,内存溢出泄漏排查,jvm调优。我这里说的只是冰山一角,详细八股可以去网上找,这不用去买,都免费资源。mysql、redis可以去看小林coding,我看你简历上写了,你一定要熟,什么底层b+树、索引结构、innodb、mvcc、undo log、redo log、行级锁表级锁,这些东西高频出现,如果面试官问我这些我都能笑出来。消息队列rabbitmq也好kafka也好,学一种就行,什么分区啊副本啊确认机制啊怎么保证不重复消费、怎么保证消息不丢失这些基本的一定要会,进阶一点的比如LEO、高水位线、kafka和rocketmq底层零拷贝的区别等等。计算机网络和操作系统既然你是科班应该理解起来问题不大,去看小林coding这两块吧,深度够了。spring boot的八股好好看看吧,一般字节腾讯不这么问,其他的java大厂挺爱问的,什么循环依赖啥的去网上看看。数据结构的话科班应该问题不大,多去力扣集中突击刷题吧。项目的话其实说白了还是结合八股来,想一想你写的这些技术会给你挖什么坑。除此之外,还有场景题、rpc、设计模式、linux命令、ddd等。不会的就别往简历上写了,虽然技术栈很多的话好看些,但背起来确实累。总结一下,多去实习吧,多跳槽,直到跳到一个不错的中厂做跳板,这是一条可行的进大厂的路线。另外,只想找个小厂的工作的话,没必要全都照这些准备,太累了,重点放在框架的使用和一些基础八股吧。大致路线就这样,没啥太多难度,就是量大,你能达到什么高度取决于你对自己多狠,祝好。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务