Project Euler problem 66

pell方程及连分数

wiki如下

http://zh.wikipedia.org/wiki/%E9%80%A3%E5%88%86%E6%95%B8

http://zh.wikipedia.org/zh-cn/%E4%BD%A9%E5%B0%94%E6%96%B9%E7%A8%8B


主要应用的是 

对于连分数 [a_0;a_1,a_2,\ldots],前四个收敛(编号 0 到 3)是

\frac{a_0}{1},\qquad\frac{a_1a_0+1}{a_1},\qquad\frac{    a_2(a_1a_0+1)+a_0}{a_2a_1+1},\qquad\frac{a_3(a_2(a_1a_0+1)+a_0)+(a_1a_0+1)}{a_3(a_2a_1+1)+a_1}

用普通语言来说,第 3 个收敛的分子是借由第 3 个商(a_2 \;)乘上第 2 个收敛的分子,并加上第 1 个收敛的分子而成。分母的形成也很类似。

如果找到连续的收敛,带有分子 h_1,h_2,\ldots 和分母 k_1,k_2,\ldots,则相关的递归关系是:

h_n=a_nh_{n-1}+h_{n-2},\qquadk_n=a_nk_{n-1}+k_{n-2}

连续的收敛由如下公式给出

\frac{h_n}{k_n}=\frac{a_nh_{n-1}+h_{n-2}}{a_nk_{n-1}+k_{n-2}}

如果 a0a1a2, ... 是正整数的无限序列,递归的定义序列 h_n 和 k_n

h_{n}=a_nh_{n-1}+h_{n-2}\,  h_{-1}=1\, h_{-2}=0\,
k_{n}=a_nk_{n-1}+k_{n-2}\,  k_{-1}=0\, k_{-2}=1\,
然后是pell方程的理论


\tfrac{p_i}{q_i} 是\sqrt{n}的连分数表示:[a_{0}; a_{1}, a_{2}, a_{3}, \,\ldots ]的渐近分数列,由连分数理论知存在 i 使得(pi,qi) 为佩尔方程的解。取其中最小的 i,将对应的 (pi,qi) 称为佩尔方程的基本解,或最小解,记作(x1,y1)

例如:
\displaystyle x^2 - 7 y^2 = 1.

首先根据根号7的渐进连分数表示,找出前几项,察看(分子,分母)是否是一组解。

第一项: \tfrac{h}{k} = \tfrac{2}{1},  h^2 - 7 k^2 = -3,\,\!不是解;
第二项: \tfrac{h}{k} = \tfrac{3}{1},  h^2 - 7 k^2 = 2,\,\! 不是解;
第三项: \tfrac{h}{k} = \tfrac{5}{2},  h^2 - 7 k^2 = -3,\,\!不是解;
第四项: \tfrac{h}{k} = \tfrac{8}{3},  h^2 - 7 k^2 = 1.\,\! 是解。

于是最小解是(8,3)。计算x_1 + y_1\sqrt n的各次乘方,或者用递推公式(不能直接得出某一项)就可以得到接下来的各组解

(8,3)、 (127,48)、 (2024,765)、 (32257,12192)、 (514088,194307)、 (8193151;3096720)、 (130576328,49353213) ......



然后我就可以用python写代码咯

import math
def gao(n):  
	m = int(math.sqrt(n))  
	if m * m == n:  
		return 0 
	ha = 1; ka = 0
	d = m  
	a = n  
	b = -m  
	c = 1
	hb = d; kb = 1
	if hb * hb - n * kb * kb == 1:
		return hb
	while True:  
		nc =  a - b * b  
		nc /= c  
		nd = int((math.sqrt(a) - b) / nc)  
		nb = -b - nd * nc
		c = nc; d = nd; b = nb;
		hc = d * hb + ha
		kc = d * kb + ka
		ha = hb
		ka = kb
		hb = hc
		kb = kc
		if hc * hc - n * kc * kc == 1:
			return hc
	return 0
ans = 0
tmp = 0
for i in range(1, 1001):
	z = gao(i)
	if z > tmp:
		tmp = z
		ans = i
print ans


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值