【蓝桥杯选拔赛真题80】python抽取扑克牌 第十五届青少年组蓝桥杯python选拔赛真题 算法思维真题解析-LMLPHP

目录

python抽取扑克牌

一、题目要求

1、编程实现

2、输入输出

二、算法分析

三、程序编写

四、程序说明

五、运行结果

六、考点分析

七、 推荐资料

1、蓝桥杯比赛

2、考级资料

3、其它资料


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

二、算法分析

  1. 题目相对而言有一点复杂,关键在于抽牌的机制
  2. 其实这题较为简单粗暴的一种解法就是采用模拟+枚举的方式来完成
  3. 先获取到对应的扑克牌,然后依次模拟抽牌的过程,先计算出有多少种可能
  4. 然后枚举每一种可能的抽牌过程,每次都是a先抽b后抽,可以使用抽牌次数进行奇偶校验实现,然后如何实现抽上面还是抽下面,可以使用位运算实现
  5. 每一种抽牌完成后只要比较一下总的点数,如果是a的点数大就累加记录即可
  6. 最后输出结果

三、程序编写

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)

四、程序说明

  1. 利用input输入函数从键盘获取扑克牌数量
  2. 利用int函数将n转换成整数类型
  3. 利用split函数以及map函数从输入中获取每张牌的积分pork
  4. 计算抽牌总数count,表示所有可能的抽牌顺序数量。通过计算2的(n-1)次方得到
  5. 初始化变量win为0,用于记录a胜利的次数
  6. 循环从1到count,表示抽牌顺序的可能情况
  7. 对于每种抽牌顺序,使用变量k来表示当前抽牌次数,a和b分别表示a和b的积分和,x和y表示当前抽牌的牌堆索引
  8. 对于每一次抽牌,当j为偶数时表示a抽牌,当j为奇数时表示b抽牌
  9. 使用位运算判断当前抽牌顺序的第k位是0还是1,当k&1为1时,表示抽上面一张牌,此时a(或b)的积分加上上面一张牌的积分,并将x加1(或y减1)。当k&1为0时,表示抽下面一张牌,同样操作,将y加1(或x减1)
  10. 在每一次抽牌之后,将k右移一位,即k>>=1,来处理下一次抽牌
  11. 当循环结束后,判断a和b的积分,如果a大于b,则win加1
  12. 循环结束后,输出win的值,表示a胜利的次数。

PS:本题也可以有更优化的解法,欢迎评论区留言

五、运行结果

3
3 2 1

4
3

六、考点分析

难度级别:中等,这题相对而言还是有一点小难度,难在解题思路,具体主要考查如下:

  1. 学会分析题目,找到解题思路
  2. 学会简单的算法知识的应用
  3. input函数:Python 中 input() 函数接受一个标准输入数据,返回为 string 类型。
  4. int函数:强制将传入对象转换成整数类型
  5. split函数:按照指定的分隔符进行分割
  6. map函数:将指定的对象按照指定的函数进行迭代,在这里是将时分秒字符串类型数据按int整数类型数字返回输出(相当于多个变量强制类型转化)
  7. list函数:强制将参数转化成列表对象
  8. 学会列表的相关操作:列表声明、取数、遍历等等
  9. 学会for循环的使用:for循环可以遍历任何有序的项及列表元素等等。
  10. range函数:rang(a,b),循环的时候是不包括b的,所以我们这个案例中要转变一下,要想包含b,就应该写成range(a,b+1)
  11. 学会if...else双分支语句的使用:满足条件执行一种处理程序,不满足执行另一种处理程序
  12. print函数:用于打印输出,最常见的一个函数。
  13. 充分掌握for循环和列表相关操作函数的使用以及暴力算法的应用

PS:方式方法有多种,小朋友们只要能够达到题目要求即可!

七、 推荐资料

1、蓝桥杯比赛

2、考级资料

3、其它资料

10-28 02:35