日期:2026年2月28日
ZeroJudge 題目連結:c093. 00608 - Counterfeit Dollar
解題想法
這題的困難之處在於分析測量結果,詳情請參考下方程式碼之中的註解。我是用集合儲存硬幣資料,由於 Python 的集合可以直接取聯集 (union)、差集 (difference),寫起來比較簡單。
Python 程式碼
使用時間約為 7 ms,記憶體約為 3 MB,通過測試。
T = int(input()) # T 組測資
for _ in range(T):
""" 前置作業 """
data = [] # 測試資料,內容為 [left, right, satatus]
coins = set() # 所有參與測試的硬幣
status = dict() # 硬幣狀態,內容為 name: [light possible, heavy possible]
for _ in range(3): # 讀取 3 次測試結果
left, right, state = input().split() # 左側硬幣,右側硬幣,右側狀態
data.append([left, right, state]) # 資料加到 data
for coin in left: coins.add(coin) # 更新 coins
for coin in right: coins.add(coin)
for coin in coins: # 更新 status,預設值為 [True, True]
status[coin] = [True, True]
""" 處理測試資料 """
for left, right, state in data: # 依序讀取測試資料
if state == "even": # 如果兩側平衡,左、右的硬幣都是真的
for coin in left: status[coin] = [False, False] # 更新 status,兩種狀態都是 False
for coin in right: status[coin] = [False, False]
elif state == "up": # 如果右側較高,代表左側較重、右側較輕,假的硬幣一定在這些硬幣之中
leri = set(left).union(set(right)) # 兩側硬幣的聯集
for coin in coins.difference(leri): # 沒有參與這次測試的硬幣都是真的
status[coin] = [False, False]
for coin in left: status[coin][0] = False # 左側硬幣不可能比真的硬幣輕
for coin in right: status[coin][1] = False # 右側硬幣不可能比真的硬幣重
else: # 如果右側較低,代表左側較輕、右側較重,假的硬幣一定在這些硬幣之中
leri = set(left).union(set(right)) # 兩側硬幣的聯集
for coin in coins.difference(leri): # 沒有參與這次測試的硬幣都是真的
status[coin] = [False, False]
for coin in left: status[coin][1] = False # 左側硬幣不可能比真的硬幣重
for coin in right: status[coin][0] = False # 右側硬幣不可能比真的硬幣輕
""" 結束測試,找答案 """
fake, result = "", "" # 假的硬幣名稱、狀態
for coin, (light, heavy) in status.items(): # 依序讀取 status 的資料
if light and not heavy: # 如果這個硬幣可能比較輕、不可能比較重
fake = coin # 找到假的硬幣
result = "light" # 較輕
break # 中止迴圈
if not light and heavy: # 如果這個硬幣不可能比較輕、可能比較重
fake = coin # 找到假的硬幣
result = "heavy" # 較重
break # 中止迴圈
print(f"{fake:s} is the counterfeit coin and it is {result:s}.")