寻找最大葫芦|青训营笔记

273 阅读5分钟

问题描述

在一场经典的德州扑克游戏中,有一种牌型叫做“葫芦”。“葫芦”由五张牌组成,其中包括三张相同牌面值的牌 a 和另外两张相同牌面值的牌 b。如果两个人同时拥有“葫芦”,我们会优先比较牌 a 的大小,若牌 a 相同则再比较牌 b 的大小。

在这个问题中,我们对“葫芦”增加了一个限制:组成“葫芦”的五张牌牌面值之和不能超过给定的最大值 maxmax。牌面值的大小规则为:A > K > Q > J > 10 > 9 > ... > 2,其中 A 的牌面值为1,K 为13,依此类推。

给定一组牌,你需要找到符合规则的最大的“葫芦”组合,并输出其中三张相同的牌面和两张相同的牌面。如果找不到符合条件的“葫芦”,则输出 “0, 0”。

题目分析

题目要求

“葫芦”由三张相同牌面值的牌a和另外两张相同牌面值的牌b组成。(注意:一副牌相同牌面值的牌最多只有4张,所以不会出现a和b相同的情况)优先比较牌a的大小,牌a相同则再比较牌b大小。

同时给了一个限定值,要求找到的“葫芦”的五张牌牌面值之和不能超过限定值。

解题思路

返回“0,0”的情况

1、如果一组牌中找不到3张相同牌面值的牌或者找不到2张相同牌面值,找不到葫芦。

2、如果所有的“葫芦”的五张牌牌面值之和都超过限定值。

因此,我们需要先找出所有的“葫芦”组合。

A列表用来记录拥有3张及以上相同牌面值的牌a,B列表用来记录拥有2张及以上相同牌面值的牌b。(注意:A列表是B列表的子集)

找到最大牌面值

由题意可知,我们应当尽可能地保证牌a的值取得最大值,再去找到牌b的最大牌面值。

因此,我们应当对A列表、B列表中的数据按照牌面值的大小规则进行排序。

并且要先分析A列表,再分析B列表

代码

    leng=len(array)
    A=[]
    B=[]
    array1=[]
    n=0
    m=0
    for i in range(leng-1):
        for j in range(leng-i-1):
            if array[j]<array[j+1]:
                temp=array[j]
                array[j]=array[j+1]
                array[j+1]=temp
    for i in array:
        if i==1:
            array1.append(1)
            n+=1
    if n==0:
        array1+=array
    else:
        for i in range(n):
            array.pop()
        array1+=array
    for i in array1:
        if array1.count(i)>=3 and i not in A:
            A.append(i)
        if array1.count(i)>=2 and i not in B:
            B.append(i)
    if len(A)==0 or len(B)==0:
        return[0,0]
    for i in A:
        m+=1
        way=B.index(i)
        B.remove(i)
        for j in B:
            sum=2*j+3*i
            if sum<=max:
                return[i,j]
            else:continue
        B.insert(way,i)
        if m==len(A):
            return[0,0]

代码分析

    leng=len(array)  #用于遍历array数组
    A=[]   #创建A列表(存放拥有3张及以上相同牌面值的牌a)
    B=[]   #创建B列表(存放拥有2张及以上相同牌面值的牌b)
    array1=[]  #将array按照牌面值大小规则排序
    n=0   #一个用于判断的数值
    m=0   

这一段在进行初始化,进行后续代码的准备。

    for i in range(leng-1):              #冒泡排序实现降序排序
        for j in range(leng-i-1):
            if array[j]<array[j+1]:
                temp=array[j]
                array[j]=array[j+1]
                array[j+1]=temp
    for i in array:                      #将1牌面值提前到array1数组的开头
        if i==1:                         #如果array中包含了1,将1放入array1的开头
            array1.append(1)
            n+=1                         #记录array中1的个数
    if n==0:                             #如果array中没有1,array数组已经是按照牌面值大小规则排序
        array1+=array
    else:                                #如果array中有1,将array中的1删除再添加到array1后
        for i in range(n):
            array.pop()
        array1+=array

这一段在将array按照牌面值大小规则进行排序。

    for i in array1:                            #count函数可以计算array某个元素的个数
        if array1.count(i)>=3 and i not in A:
            A.append(i)
        if array1.count(i)>=2 and i not in B:
            B.append(i)
    if len(A)==0 or len(B)==0:                 #判断有没有葫芦
        return[0,0]

这一段在找到牌a和牌b,并且根据1、如果一组牌中找不到3张相同牌面值的牌或者找不到2张相同牌面值,找不到葫芦。 进行判断

 for i in A:                     
        m+=1              #作为一个判断数值
        way=B.index(i)    #记录i的值在B数组的位置
        B.remove(i)       #删去B列表中的牌a数值
        for j in B:       
            sum=2*j+3*i   #用于判断牌面值之和是否超过限定值
            if sum<=max:
                return[i,j]
            else:continue
        B.insert(way,i)   #当牌a的值改变时,B列表中删去的牌a数值也要改变
        if m==len(A):     #都超过限定值,返回“00return[0,0]

这一段先找到最大的牌a,再去找最大的牌b,并且根据2、如果所有的“葫芦”的五张牌牌面值之和都超过限定值。 进行判断。如果超过,先减小b的值,如果减小b的值不行再去减小a的值。如果全部都不符合,则返回“0,0”

本段关键:因为A列表是B列表的子集,且牌a!=牌b,所以我们在选出牌a的数值时,短暂删去B列表中的牌a数值