• 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)来进行区分。

    昨天忙太晚了,没有更新题目,今天上午补上!

  • 相关阅读:
    我的暑假周记2018.7.21
    大道至简读后感
    我的暑假周记2018.7.15
    继承与多态
    java联级调用
    古罗马凯撒大帝字串加密
    作业三
    线性同余法产生1000个随机数
    Text2
    java登录界面
  • 原文地址:https://www.cnblogs.com/sunny0824/p/13449855.html
Copyright © 2020-2023  润新知