一个欧几里得扩展的应用
来源:互联网 发布:java正则匹配时间格式 编辑:程序博客网 时间:2024/06/18 08:19
前阵子从一个师兄的blog中看到个比较有意思的题目,师兄的blog中给出了多种解法,平时自个儿也不怎么研究数论,这次看到这题目感觉比较吃力,写下来以供后期参考。
题目:
5个水手在岛上发现一堆椰子, 夜晚睡觉后,第一名水手把椰子分为等量的5堆,还剩下一个给了猴子,自己藏起一堆。第二个水手把剩下的4堆混合后重新分为 等量的5堆,剩下一个给了猴子;自己藏起一堆。第三第四第五位水手依此办理。天亮以后,大家把剩下的椰子分为等量的5堆,剩下一个给了猴子。问原来这堆椰子最少为多少个。
刚接触这个问题,没什么头绪,难不成傻儿巴叽的一个个的去试,但是这肯定不是解题的方法,再继续往下看,不难看出这是一个二元一次线性方程,从最后一个海盗开始的递归:
(n-1)x=ny+1
欧几里得扩展给出了解决线性方程 的解法。
首先欧几里得算法定义ax+by=gcd(a,b)有解,证明如下:
1.显然当b=0时,gcd(a,b)=a,则x=1,y=0;
2.当a,b都不为0时,设
ax1+by1=gcd(a,b);bx2+(a%b)y2=gcd(b,a%b);/*由朴素欧几里得定理得到gcd(a,b)=gcd(b,a%b);则*/ax1+by1=bx2+(a%b)y2;ax1+by1=bx2+(a-(a/b)*b)y2=ay2+bx2-(a/b)*by2;/*根据恒等定理得到*/x1=y2; y1=x2-(a/b)*y2;
通过递归求解就可以得到x,y的值
二元线性方程ax+by=c有整数解,则c%gcd(a,b)=0,因为d=gcd(a,b)=>d|(ax+by);
#扩展欧几里得算法def extend_eulid(a,b):if b==0:return [1,0,a]else:x,y,d=extend_eulid(b,a%b)return [y,x-(a//b)*y,d]
#线性方程的求解def liner_equation(a,b,c):rst=extend_eulid(a,b)d=rst[2]x=rst[0]y=rst[1]if c%d:return NULL #线性方程的一个解k=c/dreturn [x*k,y*k]
但是此题需要求解最小的正数解,由a(x0+q*(b/d))+b(y0-q*(a/d))=c;(x0,y0是方程的一个解,d=gcd(a,b))可知,通过改变q可以得到最小正数解:
#最小正数解def liner_equation(a,b,c):rst=extend_eulid(a,b)d=rst[2]x=rst[0]y=rst[1]if c%d:return NULLk=c/dx1=x0=x*ky1=y0=y*kn=0while x1<=0:n+=1x1=x0+(b/d)*ny1=y0-(a/d)*nreturn [x1,y1]
由此,这个问题也就解决了:
#海盗个数NUM_PIRATE =5#猴子个数NUM_MONKEY=1a=NUM_PIRATE-1b=-NUM_PIRATEc=NUM_MONKEYfor i in range(NUM_PIRATE):rest=liner_equation(a,b,c)vx=rest[0]b=b*NUM_PIRATEc=NUM_MONKEY+NUM_PIRATE*vxprint vx*NUM_PIRATE+NUM_MONKEY
- 一个欧几里得扩展的应用
- 扩展欧几里得的应用
- 扩展的欧几里得算法的应用
- 再探扩展欧几里得算法的应用
- 扩展欧几里得及其应用
- 扩展欧几里得应用分析
- 欧几里得扩展应用
- 欧几里得、扩展的欧几里得算法
- 欧几里得、扩展的欧几里得算法 .
- 扩展欧几里得算法及其应用
- 扩展欧几里得算法及其应用
- 扩展欧几里得算法及其应用
- 扩展欧几里得算法 与 应用
- 扩展欧几里得算法及其应用
- 扩展欧几里得定理及其应用
- 扩展欧几里得算法及其应用
- 扩展的欧几里得算法
- 扩展的欧几里得算法
- 工控软件开发
- android in practice_Displaying splash screens with timers(MyMovies project)
- 菜鸟黑客的第一天——一些基础的手法
- Python字符编码详解
- Nginx实现负载均衡
- 一个欧几里得扩展的应用
- linux配置IP
- linux内核中的文件描述符(一)--基础知识简介
- 公元二零一三之个人读书计划
- Codeforces Beta Round #93 (Div. 2 Only)——B
- C#初体验
- soj 1176. Two Ends
- 自动编译
- underScore 源码解析(一)---- 结构