用Python形象地解决酒缸分酒问题

问题提出

你有一个8升的酒坛,里面装满了酒,另外还有两个分别是5升和3升的空酒坛,3个酒坛都没有刻度,现在需要倒出正好4升的酒,需要怎么操作?
从题目来看,我们需要把3个缸的酒倒来倒去,直到某个酒缸里面是4升酒。这个问题的解法很有趣,我们假设能装5升酒的坛子叫A,3升的坛子是B,8升的坛子是C,开始的时候我们可以先在A坛子里装满酒也可以先在B坛子装满酒(只装一部分我们是没办法知道是多少升的,没有用)。

假设先给A装满酒,那么A,B坛子的状态就是(5,0),表示这时候是A有5升酒,B有0升,这时候可以的做法是把A中的酒倒到B里,变成(2,3),也可以从C倒3升到B,变成(5,3),但这种情况下一步只能把A或B中的酒倒回C,回到开始状态了;第三种情况是把A中的酒倒进C里,变成(0,0),更加没意义了。

1,台球解法

于是有效做法是从(5,0)状态变成(2,3)状态,我们可以想象一个菱形的台球桌,从一个地方发球,球经过和桌子边缘的碰撞有一个弹射的路径。来看一下一个从(5,0)出发的球,在一个5 x 3的台球桌上,沿三角形边线方向撞击台球,其路径会是(2,3) (2,0) (0,2) (5,2) (4,3),如图
在这里插入图片描述
我们之前把(5,0)理解为A坛有5升酒,B坛有0升,那么从(5,0)到(2,3)到(2,0)就可以理解为这两个酒坛里面液体的量的变化,也就是酒坛里的状态转移路径。具体就是从A倒酒进B里,直到B满了(变成(2,3)),再把B里的酒倒到C里,变成(2,0),把B中剩余的2升倒到C里,变成(0,2),这时候把B倒满,变成(5,2),B可以装3升,目前是2升,所以从A倒酒进B里,B原来是2升,倒满就是从A倒出了1升,所以A是4升,也就是(4,3),达到要求。

实际中解这类题我们可以画x*y的菱形手动画路径,但我们可以用程序模拟这一过程,下面用Python实现一下。

3,Python 模拟

可以通过计算方向和用反射定律去模拟球的轨迹,也可以取巧只通过路径去模拟轨迹。首先这个台球桌是菱形的,出发点在(5,0)或(0,3) (都能得到结果),我们从路径上看,(5,0)只有一个路径可以走,而(2,3)有两条路可以走,分别到达(2,0)或者(5,0),在(0,0)以及(5,3)这两个点是没有路径的。
在这里插入图片描述
我们再分析路径的规律,x横坐标的最大值,y是纵坐标最大值,设n球在横坐标的位置,m为在纵坐标上的位置,对于点设n球在横坐标的位置,m为在纵坐标上的位置,对于点(n,0),n不等于0和不等于x时,都有两条路,且从一条路过来必然下一步要走另一条路,这两条路的规律是(n,y)以及(0,n),当n大于y时,到不了(0,n), 只能到(n-y,y);根据这些规律模拟出边界上各个顶点对应的路,代码如下:

'''
遇到不懂的问题?Python学习交流群:821460695满足你的需求,资料都已经上传群文件,可以自行下载!
'''

在这里插入图片描述
我们就可以从一个点(5,0)出发,看具体的效果:
在这里插入图片描述
当x=5,y=3时,以上代码输出 [[5,0],[2,3],[2,0],[0,2],[5,2],[4,3]],代表A,B两个酒缸之内各有多少酒。

4,turtle可视化

路径我们可以通过上面的代码算出来,从而得到这题的结果,但不够形象,我们通过Python的turtle库把这一过程画出来,turtle是Python内置的一个画图库,通过goto、left、right等命令控制一个小海龟(turtle)在画布(canvas)上爬行,从而得到各种图案,可以拿来绘制分形图案、小猪佩奇等。这次的模拟路径可视化也可以用pygame库。

正常的画布是一个直角坐标系,我们这里需要一个纵轴和横轴之间是60度的斜坐标系,因此通过以下函数转换:
在这里插入图片描述
通过 drawToXY()我们可以很方便地绘制出台球桌的外框:
在这里插入图片描述
绘制一个5 x 3的外框效果如下:
在这里插入图片描述
绘制外框之后再加上内部点的连接,就像把一个(X,Y)的方格变形为菱形,并加上边界坐标,在turtle上写文本通过语句 turtle.write(txt,font=(“微软雅黑”,size,“normal”))实现。
在这里插入图片描述
之后便可以绘制从(5,0)出发的球的路径了:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值