CodeSprout程式萌芽
困難第 492 題 · 收發歷程卡
CodeSprout 官方2026/10/04 00:19
官方解答 · 置頂Python

官方解答|收發歷程卡

官方解答

Python #492:收發歷程卡

解題規則

倉庫依序收到入庫、出庫或登記事件,請依本題的庫存規則處理並留下紀錄。

StockBook 複製 stock;accepted、rejected 初值均為 0,totals 初值為空清單。依 events 原順序處理 [name,amount],每筆都讀取當下數量,缺少品名視為 0。amount > 0 表示入庫 amount 件,amount < 0 表示出庫 -amount 件,amount = 0 是記錄或登記事件,不增減實際庫存。事件篩選條件為「每筆事件都進入庫存安全檢查」;候選數量一律是目前數量加上原 amount。庫存規則:候選數量須大於或等於 0。所有模式都禁止負庫存。只有事件篩選條件與庫存規則同時成立才接受,完整寫入候選數量並將 accepted 加 1。成功更新後即使數量為 0,也保留該品名。條件不成立時整筆拒絕:庫存數量及所有品名完全不變,不新增、不刪除品名,只將 rejected 加 1;不足出庫或超過倉儲上限都不能部分執行。無論接受或拒絕,每筆結束時都將全庫存數量總和加入 totals。最後回傳 [每筆事件完成後的庫存總量清單, 依品名排序的 [品名,數量] 清單]。

處理步驟

先複製 stock;每事件以目前數量加上原 amount 得到 candidate,再同時檢查事件篩選與安全庫存或倉儲上限。成功才完整寫入 candidate 並增加 accepted;拒絕時只增加 rejected,既不改數量,也不新增或刪除品名。每筆最後記錄總量。

為何正確

物件屬性保存當前狀態;負責更新的方法依當時屬性完成一次更新與必要的快照,讀值步驟只讀取目前屬性。初始化及逐次更新維持題目指定的狀態,因此最後回傳的資料符合指定摘要。

邊界與注意事項

本題輸入範圍:初始數量 0~20,amount 為 -10~10 的整數;品名為 1~10 字的 ASCII 文字;最多 12 筆事件。缺少品名的當下數量視為 0。候選數量須大於或等於 0。拒絕不得改動任何庫存鍵值。 除題目指定的篩選或移除外,保留原資料的重複項與順序;使用切片或明確判斷安全處理允許的空資料。 需要清單快照時另外複製,兩個物件的清單與計數彼此獨立。

範例追蹤

依參數順序 stock, events 傳入 [{"a":3,"b":1},[["a",-5],["b",2],["c",4],["a",2]]]。關鍵中間資料為 book = {'stock': {'a': 5, 'b': 3, 'c': 4}, 'accepted': 3, 'rejected': 1, 'totals': [4, 6, 10, 12]};name = 'a';amount = 2。最後回傳 [[4, 6, 10, 12], [['a', 5], ['b', 3], ['c', 4]]]。結果由 return 回傳,不使用 print。

複雜度

設事件數 n、過程中最大品名數 k;每步總量掃描及最後排序使時間為 O(nk+k log k),保存庫存、事件總量及輸出需要 O(n+k) 空間。

CodeSprout 官方解答 · 題意分析、解題步驟與完整參考程式

class StockBook:

    def __init__(self, stock):
        self.stock = dict(stock)
        self.accepted = 0
        self.rejected = 0
        self.totals = []

    def apply(self, name, amount):
        current = self.stock.get(name, 0)
        candidate = current + amount
        if True and candidate >= 0:
            self.stock[name] = candidate
            self.accepted += 1
        else:
            self.rejected += 1
        self.totals.append(sum(self.stock.values()))

    def report(self):
        pairs = [[name, self.stock[name]] for name in sorted(self.stock)]
        return [list(self.totals), pairs]

def solve(stock, events):
    book = StockBook(stock)
    for (name, amount) in events:
        book.apply(name, amount)
    return book.report()

留言討論 0