1. 程式人生 > 實用技巧 >Python筆試——雀魂啟動

Python筆試——雀魂啟動

題目描述:

小包最近發明了一種新的麻將,具體的規則如下:

總共有36張牌,每張牌是1~9。每個數字4張牌。
你手裡有其中的14張牌,如果這14張牌滿足如下條件,即算作和牌
14張牌中有2張相同數字的牌,稱為雀頭。
除去上述2張牌,剩下12張牌可以組成4個順子或刻子。順子的意思是遞增的連續3個數字牌(例如234,567等),刻子的意思是相同數字的3個數字牌(例如111,777)

例如:
1 1 1 2 2 2 6 6 6 7 7 7 9 9 可以組成1,2,6,7的4個刻子和9的雀頭,可以和牌
1 1 1 1 2 2 3 3 5 6 7 7 8 9 用1做雀頭,組123,123,567,789的四個順子,可以和牌

1 1 1 2 2 2 3 3 3 5 6 7 7 9 無論用1 2 3 7哪個做雀頭,都無法組成和牌的條件。

現在,小包從36張牌中抽取了13張牌,他想知道在剩下的23張牌中,再取一張牌,取到哪幾種數字牌可以和牌。

輸入描述:

輸入只有一行,包含13個數字,用空格分隔,每個數字在1~9之間

資料保證同種數字最多出現4次。

輸出描述:

輸出同樣是一行,包含1個或以上的數字。代表他再取到哪些牌可以和牌。

若滿足條件的有多種牌,請按從小到大的順序輸出。若沒有滿足條件的牌,請輸出一個數字0

思路:

原理:如果該手牌胡牌,那麼每個數字必然是,雀頭、刻子、順子的成員,
遞迴演算法 : 從最小的數字開始嘗試,如果把其當成雀頭成員,該數字劃掉兩個,並看餘下的數字能否劃空

如果是刻子成員,該數字劃掉三個,並檢視餘下數字能否劃空
如果是順子成員,劃掉該值a, a + 1, a + 2,並檢視餘下數字能否劃空
如果上述三種嘗試都無法劃空陣列,說明存在數字無法是雀頭、刻子、順子的成員,
將一個數字牌補入13個牌之中,判斷是否和牌,是則輸出,不是則下一個數字牌

程式碼實現:

getNumFromString = lambda x:list(map(int,x.strip().split()))
def isHePai(str):
    lenth = len(str)
    if lenth == 0:
        return True
    count1 = str.count(str[0])
    
# 第一個數字出現的次數 >= 2,且不是刻子,去掉雀頭剩下的能不能和牌 if lenth%3!=0 and count1>=2 and isHePai(str[2:]): return True # 第一個數字是刻子,去掉刻子剩下的能不能和牌 if count1>=3 and isHePai(str[3:]): return True # 如果存在順子,移除順子後剩下的能和牌 if str[0]+1 in str and str[0]+2 in str: str1 = str[1:] str1.remove(str[0]+1) str1.remove(str[0]+2) if isHePai(str1): return True return False if __name__ == '__main__': a = getNumFromString(input()) flag = 0 for i in range(1,10): li = sorted(a+[i]) #這裡要注意a+[i]與a.append(i)的區別(即a本身是否變化) if li.count(i)>4: continue else: # 判斷 if isHePai(li): flag = 1 print(i,end=' ') # 若到了這步說明還沒和牌 if flag == 0: print('0')

收穫:

  1. 對於列表a,a+[x] 與 a.append(x) 是有區別的,前者a不變,後者a變了。
  2. 做遞迴時,第一步一定要設定終止條件
  3. 做這類若沒有符合條件的則輸出0的題目,可以設定一個標誌位(flag)來進行區分。

昨天忙太晚了,沒有更新題目,今天上午補上!