字节跳动:雀魂启动!(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
  • 示例1
输入:1 1 1 2 2 2 5 5 5 6 6 6 9
输出:9
说明:可以组成1,2,6,7的4个刻子和9的雀头
  • 示例2
输入:1 1 1 1 2 2 3 3 5 6 7 8 9
输出:4 7
说明:用1做雀头,组123,123,567或456,789的四个顺子
  • 示例3
输入:1 1 1 2 2 2 3 3 3 5 7 7 9
输出:0
说明:来任何牌都无法和牌

逆向思维

不从已有的牌面推导出再取什么牌才能胡牌,而是看依次将所能取的牌中一张牌加入是否能听胡。所以简化为判断14张牌是否可以胡牌,即bingo。胡牌主要有三方面,一是雀头,那么只能是雀头没选择出来的情况进行选择,即当前牌数不是3的倍数;其次是刻子或顺子,只需对排除了这三张牌的牌面能否bingo。

from collections import Counter


def bingo(seq):
    if not seq:
        return True
    n = len(seq)
    first = seq.count(seq[0])
    if n % 3 != 0 and first >= 2 and bingo(seq[2:]):
        return True
    if first >= 3 and bingo(seq[3:]):
        return True
    if seq[0] + 1 in seq and seq[0] + 2 in seq:
        temp = seq[:]
        temp.remove(seq[0])
        temp.remove(seq[0]+1)
        temp.remove(seq[0]+2)
        if bingo(temp):
            return True
    return False


if __name__ == '__main__':
    current = list(map(int, input().strip().split()))
    fre = Counter(current)
    possible = set(range(1, 10)) - {fu for fu in fre if fre[fu] == 4}
    res = []
    for pu in possible:
        if bingo(sorted(current + [pu])):
            res.append(str(pu))
    if not res:
        print(0)
    else:
        print(' '.join(sorted(res)))

(最近更新:2019年09月07日)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值