摘要:

学习leetcode_365: Water and Jug Problem的解法:辗转相除相关内容(最大公约数、裴蜀定理、欧几里得算法和扩展欧几里得算法)。

正文:

1、问题描述

You are given two jugs with capacities x and y litres. There is an infinite amount of water supply available. You need to determine whether it is possible to measure exactly z litres using these two jugs.

If z liters of water is measurable, you must have z liters of water contained within one or both buckets by the end.

Operations allowed:Fill any of the jugs completely with water.

Empty any of the jugs.

Pour water from one jug into another till the other jug is completely full or the first jug itself is empty.

Example 1:

Input: x = 3, y = 5, z = 4

Output: True

(**分析**):

首先,将三个操作进行“量化”,一次倒满已知体积的壶的操作,相当于有一个(+1)*Volume,而一次将满壶水倒掉的操作,则相当于(-1)*Volume。这意味着结果可以表示为两个已知体积壶的整数线性组合:

所以,任意给定(x, y, z)且z

2、整数解存在的判据:裴蜀定理

前述方程是否有整数解的解法有一个已经存在的定理(裴蜀定理),其结论是该方程有整数解(m, n)的充要条件是z为x与y的最大公约数gcd(x, y)的倍数。也就是说,如果这个方程有整数解,那么z一定是

,反过来看,也只有当z%gcd(x,y)=0时,整数解才存在。于是,这个问题转化为求x和y的最大公约数,有辗转相除法(欧几里得算法):

(2.1)核心思想,是如下等式,对于正整数p和q(若p>q),p除以q的余数为r,则有:

由于显然有p>q>r,这个等式将两个较大数的公约数求解转化为两个较小数的公约数;

(2.2)这个最大公约数等式可以往下继续写:

其中从第一个等式开始,后式括号里的第一项为前式括号里的较小数、第二项为前式括号里较大数和较小数相除的余数。最后总能到一个余数为0的情况,此时的第一项即为p和q的最大公约数;

(2.3)这个算法可以用递归的思想很好地表达出来,python代码如下:

test of gcd:这两组数的最大公约数都是6

那么,leetcode_365就迎刃而解了,代码如下:

test of canMeasureWater:题目的example随机输入3个正整数进行测试

3、整数解的求解:扩展欧几里得算法

判断了能否测量,进一步就会思考如何进行测量呢?这个实际上就是在求前述方程的整数解。这里的解法类似于辗转相除法,也即扩展欧几里得算法。需要注意的是,由于px+qy=c的整数解从几何意义上来说是检查一条直线过整数格点的情况,所以当然可以不止一个解,而扩展欧几里得算法得到的只是其中一个。

首先从一个例子来感受一下该算法:

(a)方程系数(20, 12)变为(12, 8):

假设

,则变为:

(b)继续将(12, 8)变为(8, 4):

假设

,则变为:

(c)继续将(8, 4)变为(2, 0):

假设

,则变为:

(d)最后一个解(x3, y3)=(1, 0),那么从括号里的递推公式,依次有:(x2, y2)=(0, 1),(x1, y1)=(1, -1),(x0, y0)=(-1, 2),最后一项即为原方程的一个解。

形如

的方程总是可以用(a)-(d)来求解。整个过程和辗转相除类似(方程系数就是在做辗转相除),而且如果方程有解(c%gcd(p,q)=0),那最后的解肯定是(c/gcd(p,q), 0),因为系数辗转相除总是会到(gcd(p,q), 0)。其中变量转换的递推公式比较关键,但也很好理解,推广一下就是(//和python的整数除法定义一致):

python实现代码如下:这里先求解px+qy=gcd(p,q),再转换为px+qy=c的解;这样操作只是为了逻辑更清晰,实际上可以整合在一起(递归结束时返回值从(1, 0)变为(c/gcd(p,q), 0))px+qy=gcd(p,q)的解,求解过程不依赖于方程左边的c;以(p,q)为递归过程,再反向递归求解(x,y)

test of integer_solution:实际上还有x=-2, y=2的解,多解的原因应该是前述(c)步骤中,最后一次变量转换实际上可以不遵从递推公式

从这个结果可知,如果想用3升和5升的水壶生成4升容积,解(8,-4)意味着总共会倒入8次3升水壶、倒掉4次5升水壶,而解(-2, 2)意味着总共会倒掉2次3升水壶、倒满2次5升水壶。当然,解只是总体概括,至于具体步骤还需要进一步地分解了,不过问题就已经变得很简单了。

4、本篇内容代码的github链接gcd_euclidean_algorithm.py​github.com

python辗转相除_python(四):辗转相除相关推荐

  1. python遍历文件内容_Python四种逐行读取文件内容的方法

    下面是四种Python逐行读取文件内容的方法, 并分析了各种方法的优缺点及应用场景,以下代码在python3中测试通过, python2中运行部分代码已注释,稍加修改即可. 方法一:readline函 ...

  2. python追加写模式_python(四)文件的读写追加模式

    1.文件的读模式:也是默认的方式, f=open('文件路径\文件名','r',encoding='utf-8'):以读的模式打开一个文件,这里的'r'也可以不写,读模式是默认模式,encoding= ...

  3. 使用python排八字 计算八字的相合相冲五行分值等

    简介 八字术是一种古老的算命术.它运用阴阳.五行.干支.八卦等理论,把人的出生年月日时转化为八个字,进而推算人的富贵贫贱.祸福吉凶.穷通寿天.名利地位.家庭六亲等方面的情况 八字源自古代的中国,是一种 ...

  4. 使用python排八字 计算八字的相合相冲五行分值等...

    简介 八字术是一种古老的算命术.它运用阴阳.五行.干支.八卦等理论,把人的出生年月日时转化为八个字,进而推算人的富贵贫贱.祸福吉凶.穷通寿天.名利地位.家庭六亲等方面的情况 八字源自古代的中国,是一种 ...

  5. python求平行四边形面积_python 已知平行四边形三个点,求第四个点的案例

    我就废话不多说了,大家还是直接看代码吧! import numpy as np #已知平行四边形三个点,求第四个点 #计算两点之间的距离 def CalcEuclideanDistance(point ...

  6. python写的平行四边形_python 已知平行四边形三个点,求第四个点的案例

    我就废话不多说了,大家还是直接看代码吧! import numpy as np #已知平行四边形三个点,求第四个点 #计算两点之间的距离 def CalcEuclideanDistance(point ...

  7. python自定义函数参数_python自定义函数的参数之四种表现形式

    (1)def a(x,y):print x,y 这是最常见的定义方式,调用该函数,a(1,2)则x取1,y取2,形参与实参相对应,如果a(1)或者a(1,2,3)则会报错 (2)def a(x,y=3 ...

  8. python自学篇十[ 面向对象 (四) :王者荣耀小游戏+模拟一个简单的银行进行业务办理的类]

    python基础系列: python自学篇一[ Anaconda3安装 ] python自学篇二[ pycharm安装及使用 ] python自学篇三[ 判断语句if的使用 ] python自学篇四[ ...

  9. python算法和数据结构_Python中的数据结构和算法

    python算法和数据结构 To 至 Leonardo da Vinci 达芬奇(Leonardo da Vinci) 介绍 (Introduction) The purpose of this ar ...

最新文章

  1. python实现登录网站下载文件-Python爬虫 登录网页后下载图片,怎么保持登录状态?...
  2. posix多线程有感--API
  3. 运维开发学go还是python_运维工程师是要学python还是学go那?
  4. 跟我一起学.NetCore之Options实例演示及分析
  5. Eclipse中看不到jsp的页面效果
  6. php smtp发送附件,PHP:如何使用smtp设置发送带附件的电子邮件?
  7. sql backup database备份d盘_Oracle-备份与恢复(二)RMAN备份-自动备份计划任务脚本...
  8. java流程控制if_java程序流程控制(分支结构之 if-else)
  9. 网络互撕是群体极化的典型症状
  10. 服务器上的数据库文件夹下,服务器怎么打开数据库文件夹下
  11. 永别了.武器------爱好和平人民的美好愿望(图)
  12. 教你如何查看已经撤回的微信消息!
  13. Caused by: ParsingException[Failed to parse object: expecting token of type [START_OBJECT] but found
  14. 【专利转让】掌纹识别、图像复原、人脸检测定位相关领域
  15. android plist动画,用Lottie把启动界面动起来
  16. pytorch 中的topk函数
  17. openssl源码中的头文件include error
  18. [牛客算法总结]:青蛙跳台阶
  19. 学习笔记(34):MATLAB基础入门课程-乘方
  20. 有什么博客营销技巧?

热门文章

  1. 从巴贝奇、爱达到图灵
  2. android 不压缩保存图片格式,Android中图片的压缩方法
  3. python编写程序输出诗句_闲来无事能干嘛 用Python来玩诗歌接龙
  4. 股票价格预测 | Python实现LSTM股票价格时间序列预测
  5. mysql-日志分析
  6. laravel接合monolog实现日志记录到Elasticsearch实践
  7. 【答读者问6】如何获取哪些股票有持仓?
  8. Java实现多条相同数据合并为一条数据
  9. Corner芯片TT,FF,SS
  10. Windows远程访问服务器jupyter notebook