问题描述
在一场经典的德州扑克游戏中,有一种牌型叫做“葫芦”。“葫芦”由五张牌组成,其中包括三张相同牌面值的牌 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): #都超过限定值,返回“0,0”
return[0,0]
这一段先找到最大的牌a,再去找最大的牌b,并且根据2、如果所有的“葫芦”的五张牌牌面值之和都超过限定值。 进行判断。如果超过,先减小b的值,如果减小b的值不行再去减小a的值。如果全部都不符合,则返回“0,0”
本段关键:因为A列表是B列表的子集,且牌a!=牌b,所以我们在选出牌a的数值时,短暂删去B列表中的牌a数值