54扑克牌轮流拿问题,Python实现(详解)
拿扑克牌问题:
一个有趣的抽扑克牌问题:54张扑克牌,两人轮流拿牌,每人每次最少拿1张牌,最多拿4张牌。谁拿最后一张牌谁输。编写计算机先拿牌必胜的方法。
这个问题我们可以这样考虑:到达最后一轮时,当机器拿完牌时场上只剩下一张牌,这样对手只能拿一张牌,所以必然是机器赢。
简单说明一下思路:到最后一轮时,场上剩下{2,3,4,5}张牌 (表示场上剩下2或3或4或5张牌) 机器必赢,因为时机器每轮先拿牌,拿牌数量又在1~4,所以完全可以控制牌最后只剩下一张。但是如果剩下6张牌,机器是必输的。因为机器拿完牌之后剩下的牌必然在{2,3,4,5},到了对面拿牌,同理对面也可以控制牌只在一张,这样机器必拿最后一张牌。
通过上面这个图可以看见,只要是机器先拿牌,并且每轮场上所剩的牌在左边的区间内,机器是必赢的,因为机器每次拿完牌之后,始终让场上的牌所剩的数量让对面必输。
再分析上面的表格,我们的巧妙的发现,场上的牌如果对5求余为1的话,那么先拿牌的人是必输的。
原理分析:
每轮每个人拿牌的数量都在1~4。也就是两个人一轮拿牌的数量只要其中一个愿意那么就肯定可以控制这轮拿牌的总数量为5。(比如说A拿1张,B只要拿4张就可让这轮牌拿去的总量为5。) 那为什么不是6,3或者其它数字呢?因为后拿牌的人控制不了,规则只允许为1~4张。A拿{1,2,3,4},B只要拿{4,3,2,1}即可。
那知道每轮可以控制拿牌数量为5有什么用呢?如果场上剩余牌数为5的n倍加1(n>=1),比如6,11,16。那么后拿牌的人总是可以控制拿牌数量为5,那么每轮去掉5个。到最后一轮的时候,场上的牌只剩下一个了,又是你先拿牌,所以你必输。
问题和我们刚才分析的刚刚反过来了,问谁先拿必赢。其实原理都是一样的。场上剩下的只要不是5的n倍加1,那么你先拿牌你是必赢的。
代码实现(python)
import randomclass DrawCards:def __init__(self):self.Cards=54def machineDraw(self):while(1):n=random.randint(1,4)if (self.Cards-n-1)%5==0:self.Cards-=nprint('machine draw ',n,'crads')breakdef manDraw(self):while(1):n=input('pleasr input a numbee in 1~4\t')if int(n) in (1,2,3,4):self.Cards-=int(n)breakprint('error,please enter again')def Run(self):count=0while(self.Cards!=0):self.machineDraw()self.manDraw()count+=1print('End of round ',count,',there ',self.Cards,'left on the field\n')if self.Cards in (2,3,4,5):print('machine draw',self.Cards-1,'cards,you loss!')breakif __name__ == "__main__":start=DrawCards()start.Run()
54扑克牌轮流拿问题,Python实现(详解)相关推荐
- 【python】详解类class的继承、__init__初始化、super方法
原文链接; https://blog.csdn.net/brucewong0516/article/details/79121179?utm_medium=distribute.pc_relevant ...
- 07 Python数据类型详解
文章目录 一.整数类型(int)详解 1.1 整数的不同进制 1) 十进制形式 2) 二进制形式 3) 八进制形式 4) 十六进制形式 1.2 数字分隔符 1.3 相关方法 二.字符串类型(strin ...
- Python数据类型详解03
原文博客地址: Python数据类型详解03 第一篇Python数据类型详解01中主要介绍了Python中的一些常用的数据类型的基础知识 第二篇Python数据类型详解02文章中, 详细介绍了数字(N ...
- python区块链开发_Fabric区块链Python开发详解
Hyperledger Fabric是最流行的联盟区块链平台.Fabric区块链Python开发详解课程 涵盖Fabric区块链的核心概念.Fabric网络搭建.Node链码开发.Python应用开发 ...
- python装饰器setter_第7.27节 Python案例详解: @property装饰器定义属性访问方法getter、setter、deleter...
上节详细介绍了利用@property装饰器定义属性的语法,本节通过具体案例来进一步说明. 一. 案例说明 本节的案例是定义Rectangle(长方形)类,为了说明问题,除构造函数外,其他方法都只 ...
- python与golang_Golang与python线程详解及简单实例
Golang与python线程详解及简单实例 在GO中,开启15个线程,每个线程把全局变量遍历增加100000次,因此预测结果是 15*100000=1500000. var sum int var ...
- python 最小二乘法_最小二乘法及其python实现详解
最小二乘法Least Square Method,做为分类回归算法的基础,有着悠久的历史(由马里·勒让德于1806年提出).它通过最小化误差的平方和寻找数据的最佳函数匹配.利用最小二乘法可以简便地求得 ...
- 【python】详解multiprocessing多进程-Pool进程池模块(二)
[python]详解multiprocessing多进程-process模块(一) [python]详解multiprocessing多进程-Pool进程池模块(二) [python]详解multip ...
- 【python】什么是序列,Python序列详解
什么是序列,Python序列详解 概述 序列索引 序列切片 序列相加 序列相乘 检查元素是否包含在序列中 序列相关的内置函数 range 快速初始化数字列表 概述 所谓序列,指的是一块可存放多个值的连 ...
- python多线程详解 Python 垃圾回收机制
文章目录 python多线程详解 一.线程介绍 什么是线程 为什么要使用多线程 总结起来,使用多线程编程具有如下几个优点: 二.线程实现 自定义线程 守护线程 主线程等待子线程结束 多线程共享全局变量 ...
最新文章
- [Python]一行代码判断请求参数是否正确
- c# 学习笔记 (3) 窗体单例模式
- android源码编译烧鸡,android4.0源码下载 编译 系统体验~图解
- python集合的操作_Python集合操作方法详解
- android如何删除项目,AndroidStudio中怎样删除项目
- python坐标轴刻度设置对数_用对数刻度设置刻度
- 自定义标签之 带Body的标签库
- “命令终端”的实现2-字符读取及按键控制
- 疫情政务问答助手算法冠军开源
- java归并排序自底向上实现:
- delphi下载网站文件(支持https协议)
- html5shiv.js 的作用
- 电机驱动软件学习笔记——数据打包解包CRC校验
- windows默认共享的打开和关闭
- Xenu工具的简单使用
- r语言实现岭回归_R语言回归篇
- OpenGL缓冲区对象之FBO
- 阿里云国际版云服务器自助诊断系统-Unirech
- Android开发之仿360手机卫士悬浮窗效果
- 在外包干了几年,感觉自己都快费了
热门文章
- 详细安装sqlmap详细教程
- oracle odbc 数据源管理器 配置,ODBC管理器设置SQL server 数据源
- Java中的数据结构之常见的五种数据结构
- opencv-python 4.2 函数手册
- linux mysql 升级_linux mysql5.7升级到mysql8.0
- NSString 与 Unicode
- ASP.NET 订餐系统-程序+配置文档
- php抓取视频教程,PHP抓取、分析国内视频网站的视频信息工具类_PHP
- thinkphp tp 框架如何查看版本
- 《Java核心技术 卷II》笔记——(12)安全加密