日期:2026年3月5日
ZeroJudge 題目連結:c103. 00131 - The Psychic Poker Player
解題想法
這題我只寫了 Python 版本。我先為每一種牌型寫一個自訂函式,再用另一個自訂函式 check 檢查手牌的牌型,由高分檢查到低分。最後再寫一個自訂函式 check 測試各種換牌張數的最高分。討論區裡有一種用數學計算的寫法,但我沒有認真推導數學關係式,就沒有寫了。
Python 程式碼
使用時間約為 10 ms,記憶體約為 3.4 MB,通過測試。
import sys, itertools
def flush(hand): # 手牌是否為同花
return all(card[1] == hand[0][1] for card in hand[1:])
def straight(hand): # 手牌是否為順子
nums = {'A': 14, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7,
'8': 8, '9':9, 'T': 10, 'J': 11, 'Q': 12, 'K': 13} # 牌面數字
flag1, flag2 = True, True # 是否為 A, 2, 3, 4, 5,是否為其它號碼的順子
if hand[-1][0] == 'A': # 特例,最大的是 A,要檢查是否為 A, 2, 3, 4, 5
pre = 1 # A 當作 1
for card in hand[:-1]:
curr = nums[card[0]]
if curr != pre+1:
flag1 = False
break
pre = curr
else: flag1 = False # 最大的不是 A,不可能是 A, 2, 3, 4, 5
# 其它號碼的順子
pre = nums[hand[0][0]]
for card in hand[1:]:
curr = nums[card[0]]
if curr != pre+1:
flag2 = False
break
pre = curr
return flag1 or flag2
def straight_flush(hand): # 手牌是否為同花順
return flush(hand) and straight(hand)
def four_of_a_kind(hand): # 手牌是否為鐵支
cnt = dict() # 計數器
for card in hand: # 依序讀取手牌數值
n = card[0]
if n not in cnt: cnt[n] = 1
else: cnt[n] += 1
return max(cnt.values()) == 4 # 如果某一種數值有 4 張,是鐵支
def full_house(hand): # 手牌是否為葫蘆
cnt = dict() # 計數器
for card in hand: # 依序讀取手牌數值
n = card[0]
if n not in cnt: cnt[n] = 1
else: cnt[n] += 1
tmp = sorted(cnt.values()) # 牌面數量排序
return len(tmp) == 2 and tmp[0] == 2 and tmp[1] == 3
def three_of_a_kind(hand): # 手牌是否為三條
cnt = dict() # 計數器
for card in hand: # 依序讀取手牌數值
n = card[0]
if n not in cnt: cnt[n] = 1
else: cnt[n] += 1
tmp = sorted(cnt.values()) # 牌面數量排序
return len(tmp) == 3 and tmp[0] == 1 and tmp[1] == 1 and tmp[2] == 3
def two_pairs(hand): # 手牌是否為兩對
cnt = dict() # 計數器
for card in hand: # 依序讀取手牌數值
n = card[0]
if n not in cnt: cnt[n] = 1
else: cnt[n] += 1
tmp = sorted(cnt.values()) # 牌面數量排序
return len(tmp) == 3 and tmp[0] == 1 and tmp[1] == 2 and tmp[2] == 2
def one_pair(hand): # 手牌是否為一對
cnt = dict() # 計數器
for card in hand: # 依序讀取手牌數值
n = card[0]
if n not in cnt: cnt[n] = 1
else: cnt[n] += 1
tmp = sorted(cnt.values()) # 牌面數量排序
return len(tmp) == 4 and tmp[0] == 1 and tmp[1] == 1 and tmp[2] == 1 and tmp[3] == 2
def check(hand):
if straight_flush(hand): return 8
if four_of_a_kind(hand): return 7
if full_house(hand): return 6
if flush(hand): return 5
if straight(hand): return 4
if three_of_a_kind(hand): return 3
if two_pairs(hand): return 2
if one_pair(hand): return 1
return 0
def change(hand, deck): # 輸入手牌、牌庫,依序檢查
result = [[0, i] for i in range(6)] # 從牌庫換 0 ~ 5 張牌可組成的最大組合,[組合, 換牌數量]
result[0][0] = check(hand)
# 換一張牌,測試換第一張 ~ 第五張的效果
best = 0
for i in range(5):
tmp = hand[:i] + hand[i+1:] + [deck[0]]
tmp.sort(key = lambda x : (nums[x[0]], shdc[x[1]]))
best = max(best, check(tmp))
result[1][0] = best
# 換二張牌,測試換其中兩張牌的效果
best = 0
for i, j in itertools.combinations(range(5), 2):
tmp = hand.copy()
tmp.remove(hand[i])
tmp.remove(hand[j])
tmp += deck[:2]
tmp.sort(key = lambda x : (nums[x[0]], shdc[x[1]]))
best = max(best, check(tmp))
result[2][0] = best
# 換三張牌,測試換其中三張牌的效果
best = 0
for i, j, k in itertools.combinations(range(5), 3):
tmp = hand.copy()
tmp.remove(hand[i])
tmp.remove(hand[j])
tmp.remove(hand[k])
tmp += deck[:3]
tmp.sort(key = lambda x : (nums[x[0]], shdc[x[1]]))
best = max(best, check(tmp))
result[3][0] = best
# 換四張牌,測試只留其中一張牌的效果
best = 0
for i in range(5):
tmp = [hand[i]] + deck[:4]
tmp.sort(key = lambda x : (nums[x[0]], shdc[x[1]]))
best = max(best, check(tmp))
result[4][0] = best
# 全換
result[5][0] = check(deck)
result.sort(reverse=True)
return result[0]
for line in sys.stdin:
hand = line.split()[:5]
deck = line.split()[5:]
nums = {'A': 14, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7,
'8': 8, '9':9, 'T': 10, 'J': 11, 'Q': 12, 'K': 13} # 牌面數字
shdc = {'S': 0, 'H': 1, 'D': 2, 'C': 3} # 花色
comb = ("highest-card", "one-pair", "two-pairs", "three-of-a-kind", "straight",
"flush", "full-house", "four-of-a-kind", "straight-flush")
sorted_hand = sorted(hand, key = lambda x : (nums[x[0]], shdc[x[1]])) # 數字、花色由小到大排序
best_comb, change_cards = change(sorted_hand, deck)
print("Hand: ", end="")
print(*hand, end=" ")
print("Deck: ", end="")
print(*deck, end=" ")
print(f"Best hand: {comb[best_comb]:s}")