目录
python抽取扑克牌
第十五届蓝桥杯青少年组python比赛选拔赛真题
一、题目要求
(注:input()输入函数的括号中不允许添加任何信息)
1、编程实现
有 N 张扑克牌叠放在桌上,A 和 B 两人轮流抽牌,每次只能从最上面或最下面抽一张牌,当最后一张牌被抽完时,比较 A和 8 两人扑克牌的点数总和,点数总和大的一方胜利,点数相同时双方均不算胜利。A先抽牌,请统计一共有多少种不同的抽牌情况,A 有多少种不同的获胜情况。
例如:N=3,有3张扑克牌,从上往下的点数依次为 3、2、1。A 先抽牌,所有不同的抽取情况有:第一种:A抽3,B抽1,A再抽 2,A的点数总和为5,B的点数总和为1;第二种:A抽3,B抽2,A再抽1,A的点数总和为4,B 的点数总和为 2;第三种:A抽1,B抽3,A再抽2,A的点数总和为3,8的点数总和为3;第四种:A抽1,B抽2,A再抽3,A的点数总和为4,B的点数总和为 2;一共有 4 种不同的抽牌情况,A 有 3 种不同的获胜情况。
2、输入输出
输入描述:第一行输入一个整数 N(2≤N≤20),表示扑克牌的张数
第二行输入 N 个整数(1<整数≤13),同一个整数不能出现超过 4 次,表示从上往下每张扑克牌的点数 ,整数之间以一个空格隔开
输出描述:第一行输出一个整数,表示一共有多少种不同的抽牌情况
第二行输出一个整数,表示 A有多少种不同的获胜情况
输入样例:
3
3 2 1
输出样例:
4
3
二、算法分析
- 题目相对而言有一点复杂,关键在于抽牌的机制
- 其实这题较为简单粗暴的一种解法就是采用模拟+枚举的方式来完成
- 先获取到对应的扑克牌,然后依次模拟抽牌的过程,先计算出有多少种可能
- 然后枚举每一种可能的抽牌过程,每次都是a先抽b后抽,可以使用抽牌次数进行奇偶校验实现,然后如何实现抽上面还是抽下面,可以使用位运算实现
- 每一种抽牌完成后只要比较一下总的点数,如果是a的点数大就累加记录即可
- 最后输出结果
三、程序编写
n = int(input())
pork = list(map(int,input().split()));
count = pow(2,n-1)#表示抽牌总数
print(count)
win = 0
for i in range(1,count+1):
k,a,b,x,y = i,0,0,0,n-1 #k是第几次,a和b为对应积分和,x和y为索引
for j in range(n):
if j%2 == 0: #a抽牌
if k & 1: #取上面
a += pork[x]
x += 1
else:
a += pork[y]
y -= 1
else: #b抽牌
if k & 1:
b += pork[x]
x += 1
else:
b += pork[y]
y -= 1
k>>=1
if a > b:
win += 1
print(win)
四、程序说明
- 利用input输入函数从键盘获取扑克牌数量
- 利用int函数将n转换成整数类型
- 利用split函数以及map函数从输入中获取每张牌的积分pork
- 计算抽牌总数count,表示所有可能的抽牌顺序数量。通过计算2的(n-1)次方得到
- 初始化变量win为0,用于记录a胜利的次数
- 循环从1到count,表示抽牌顺序的可能情况
- 对于每种抽牌顺序,使用变量k来表示当前抽牌次数,a和b分别表示a和b的积分和,x和y表示当前抽牌的牌堆索引
- 对于每一次抽牌,当j为偶数时表示a抽牌,当j为奇数时表示b抽牌
- 使用位运算判断当前抽牌顺序的第k位是0还是1,当k&1为1时,表示抽上面一张牌,此时a(或b)的积分加上上面一张牌的积分,并将x加1(或y减1)。当k&1为0时,表示抽下面一张牌,同样操作,将y加1(或x减1)
- 在每一次抽牌之后,将k右移一位,即k>>=1,来处理下一次抽牌
- 当循环结束后,判断a和b的积分,如果a大于b,则win加1
- 循环结束后,输出win的值,表示a胜利的次数。
PS:本题也可以有更优化的解法,欢迎评论区留言
五、运行结果
3
3 2 1
4
3
六、考点分析
难度级别:中等,这题相对而言还是有一点小难度,难在解题思路,具体主要考查如下:
- 学会分析题目,找到解题思路
- 学会简单的算法知识的应用
- input函数:Python 中 input() 函数接受一个标准输入数据,返回为 string 类型。
- int函数:强制将传入对象转换成整数类型
- split函数:按照指定的分隔符进行分割
- map函数:将指定的对象按照指定的函数进行迭代,在这里是将时分秒字符串类型数据按int整数类型数字返回输出(相当于多个变量强制类型转化)
- list函数:强制将参数转化成列表对象
- 学会列表的相关操作:列表声明、取数、遍历等等
- 学会for循环的使用:for循环可以遍历任何有序的项及列表元素等等。
- range函数:rang(a,b),循环的时候是不包括b的,所以我们这个案例中要转变一下,要想包含b,就应该写成range(a,b+1)
- 学会if...else双分支语句的使用:满足条件执行一种处理程序,不满足执行另一种处理程序
- print函数:用于打印输出,最常见的一个函数。
- 充分掌握for循环和列表相关操作函数的使用以及暴力算法的应用
PS:方式方法有多种,小朋友们只要能够达到题目要求即可!