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

自动售货系统

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

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

最折磨的苦力题目

全部评论

相关推荐

不愿透露姓名的神秘牛友
昨天 18:54
点赞 评论 收藏
分享
找不到工作死了算了:没事的,雨英,hr肯主动告知结果已经超越大部分hr了
点赞 评论 收藏
分享
躺尸修仙中:因为很多92的也去卷中小厂,反正投递简历不要钱,面试不要钱,时间冲突就推,不冲突就面试积累经验
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务