欧拉工程第66题:Diophantine equation

题目链接

脑补知识:佩尔方差

上面说的貌似很明白,最小的i,对应最小的解

然而我理解成,一个循环的解了,然后就是搞不对,后来,仔细看+手工推导发现了问题。i从0开始变量,知道第一个满足等式的解就是最小解。

问题转化为求根号n的连分数问题,分子就是x,分母就是y

要求的分子,分母,问题又转化为:根号n的连分数表示,对,求出其连分数表示就OK了

先求出a的序列是什么?

第64题,就是求a的序列的。

a求出来了,要求出分子分母的表达式。

第65题,就是已经知道了a的序列,求分子,当然也可以求分母的

分子,分母求出来了,在验证:X*X-D*Y*Y=1时候就是最小解

问题真是一环套一环的。

Python程序:

import time as time 

start = time.time()

def getD(N):
    x_max ,y_max= 0,0
    D = 0
    x,y = 0,0
    for S in range(2,N+1):
        x,y = resolve(S)
        if x>x_max:
            x_max ,y_max= x,y
            D = S
    return D,x_max,y_max

def resolve(S):
    m = 0
    d = 1
    a0 = int(S**0.5)
    if a0*a0 == S :return -1,-1;
    a= a0
    li = [a]
    x,y = 1,1
    while x*x-S*y*y!=1:
        m = d*a - m
        d = (S - m*m)/d
        a = int((a0 + m)/d)
        li.append(a)
        x = getX(li)
        y = getY(li)
#     print li
    return x,y;

def getX(li):
    x0 = 1
    x1 = li[0]
    li = li[1:]
    for l in li:
        x = l * x1 + x0
        x0 = x1
        x1 = x
    return x 

def getY(li):
    y0 = 0
    y1 = 1
    li = li[1:]
    for l in li:
        y = l * y1 + y0
        y0 = y1
        y1 = y
    return y 

if __name__ == ‘__main__‘:

    start = time.time()
    N = 1000
    D ,x_max,y_max= getD(N)
    print "running time={0}seconds,D={1},x_max={2},y_max={3}".format(time.time()-start,D,x_max,y_max)

求的是最小解X的最大值时候的D,答案是661

然而:

x_max=16421658242965910275055840472270471049

y_max=638728478116949861246791167518480580

这个值好大的

附一:python程序:

from math import sqrt
from time import time

def prefect_sqrt(n):
    return int(sqrt(n))**2 == n 

def floor_root(n):
    return int(sqrt(n))

def chakravals(n):
    x_max = 0
    for d in range(2,n+1):
        if not prefect_sqrt(d):
            p1 = floor_root(d)
            q1 = 1
            m1 = p1**2 - d
#             print -p1,(-p1) % abs(m1),(-p1) % abs(m1)
            if (-p1) % abs(m1) ==0:
                x1 = abs(m1)
            else:
                x1 = (-p1) % abs(m1)

            while m1!=1:
                p0 = p1
                q0 = q1
                m0 = m1
                x0 = x1

                p1 = (p0 * x0 +d *q0)/abs(m0)
                q1 = (p0 + x0)/abs(m0)

                m1 = (x0**2 -d)/m0 

                if (-x0)%abs(m1) ==0:
                    x1 = abs(x0)
                else:
                    x1 = (-x0)%abs(m1)
            if p1>x_max:
                x_max = p1
                d_max = d
                print "d= %04d  x = %d"%(d_max,x_max)
    print 

if __name__==‘__main__‘:
    start = time()
    chakravals(1000)
    end = time()
    print "time elapse=%f"%(end - start)

Java程序:

这个跑的好慢的

package project61;
import java.math.*;  

public class P66
{
    public static final int precision = 500;
    public static void main( String args[] )
    {
        BigInteger Max = new BigInteger("0");
        int ans = 0;  

outer:  for (int D_i = 2; D_i <= 1000; D_i++)
        {
            BigDecimal D = new BigDecimal(D_i);
            BigDecimal SD = calculation.Sqrt(D);  

            BigDecimal SD_i = SD.setScale(0, BigDecimal.ROUND_FLOOR);
            if (SD_i.multiply(SD_i).equals(D))
                continue;  

            int a[] = calculation.toContinuedFraction(SD, 100);  

            for (int i = 1; i < 100; i++)
            {
                Fraction temp = new Fraction(a[i],1);  

                for (int j = i - 1; j >= 0; j--)
                    temp = Fraction.Compute(a[j], temp);  

                BigInteger y_2 = temp.denominator.multiply(temp.denominator);
                BigInteger x_2 = temp.numerator.multiply(temp.numerator);
                BigInteger result = x_2.subtract(y_2.multiply(D.toBigIntegerExact())).subtract(BigInteger.ONE);  

                if (result.equals(BigInteger.ZERO))
                {
                    if (temp.numerator.compareTo(Max) > 0)
                    {
                        Max = temp.numerator;
                        ans = D_i;
                    }  

                    continue outer;
                }  

            }
            System.out.print("Warning!\n");  

        }
        System.out.print(ans+"\n");
    }
}  

class Fraction
{
    public BigInteger numerator;
    public BigInteger denominator;  

    private Fraction()
    {  

    }
    public Fraction (int numerator, int denominator)
    {
        this.numerator = BigInteger.valueOf(numerator);
        this.denominator = BigInteger.valueOf(denominator);
    }
    public static Fraction Compute(int p1, Fraction p2)
    {
        Fraction ans = new Fraction();
        ans.numerator = p2.denominator.add(p2.numerator.multiply(BigInteger.valueOf(p1)));
        ans.denominator = p2.numerator.add(BigInteger.ZERO);
        return ans;
    }
}  

class calculation
{
    private static final BigDecimal N0 = new BigDecimal(0);
    private static final BigDecimal N1 = new BigDecimal(1);
    private static final BigDecimal N2 = new BigDecimal(2);  

    public static BigDecimal Sqrt(BigDecimal In)
    {
        BigDecimal N = new BigDecimal(1);
        while(true)
        {
            BigDecimal NN = N.multiply(N);
            NN = NN.add(In);
            NN = NN.divide(N2);
            NN = NN.divide(N, P66.precision, BigDecimal.ROUND_FLOOR);  

            if (NN.equals(N))
                break;  

            N = NN;
        }  

        return N;
    }
    public static int[] toContinuedFraction(BigDecimal In, int l)
    {
        int ans[] = new int[l];  

        BigDecimal temp = In.add(N0);
        for (int i = 0; i < l; i++)
        {
            ans[i] = Integer.valueOf(temp.setScale(0, BigDecimal.ROUND_FLOOR).toString()).intValue();
            temp = temp.subtract(temp.setScale(0, BigDecimal.ROUND_FLOOR));
            temp = N1.divide(temp, P66.precision, BigDecimal.ROUND_FLOOR);
        }
        return ans;
    }
}

最后两个程序在网上复制过来的

时间: 2024-08-01 10:32:59

欧拉工程第66题:Diophantine equation的相关文章

欧拉工程第70题:Totient permutation

题目链接 和上面几题差不多的 Euler's Totient function, φ(n) [sometimes called the phi function]:小于等于n的数并且和n是互质的数的个数 存在这样的数:N的欧拉数φ(n),是N的一个排列 例如:φ(87109)=79180 求在1---10^7中n/φ(n) 取到最小的 n 是多少? 这里的是p是n的素因子,当素因子有相同的时候只取一个 任意一个正整数都能分解成若干个素数乘积的形式 直接利用上题的phi函数就可以求解 这个是跑的最

欧拉工程第67题:Maximum path sum II

By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23. 37 42 4 68 5 9 3 That is, 3 + 7 + 4 + 9 = 23. Find the maximum total from top to bottom in triangle.txt (right c

欧拉工程第65题:Convergents of e

题目链接 现在做这个题目真是千万只草泥马在心中路过 这个与上面一题差不多 这个题目是求e的第100个分数表达式中分子的各位数之和 What is most surprising is that the important mathematical constant,e = [2; 1,2,1, 1,4,1, 1,6,1 , ... , 1,2k,1, ...]. The first ten terms in the sequence of convergents for e are: 2, 3,

欧拉工程第71题:Ordered fractions

题目链接:https://projecteuler.net/problem=71 If n<d and HCF(n,d)=1, it is called a reduced proper fraction. n/d 真分数升序排序后,离 3/7最近的数,d<=1000000 Java程序: public class P71{ void run(){ calculate(); } void calculate(){ int max_n = 1000000; long a = 3; long b

欧拉工程第73题:Counting fractions in a range

题目链接:https://projecteuler.net/problem=73 n/d的真分数 ,当d<=12000时 在 1/3 and 1/2 之间的有多少个 public class P73{ void run(){ FareySequences(); } void FareySequences(){ int limit = 12000; int a = 1; int b = 3; int c = 4000; int d = 11999; int count=0; while(!(c==

欧拉工程第51题:Prime digit replacements

题目链接 题目: 通过置换*3的第一位得到的9个数中,有六个是质数:13,23,43,53,73和83. 通过用同样的数字置换56**3的第三位和第四位,这个五位数是第一个能够得到七个质数的数字,得到的质数是:56003, 56113, 56333, 56443, 56663, 56773, 和 56993.因此其中最小的56003就是具有这个性质的最小的质数. 找出最小的质数,通过用同样的数字置换其中的一部分(不一定是相邻的部分),能够得到八个质数. 解题思想: 这个题目是很难的 你首先要找到

欧拉工程第52题:Permuted multiples

题目链接 题目: 125874和它的二倍,251748, 包含着同样的数字,只是顺序不同. 找出最小的正整数x,使得 2x, 3x, 4x, 5x, 和6x都包含同样的数字. 这个题目相对比较简单 暴力遍历 判断x,2x,3x,4x,5x,6x是否包含的数字相同 如何判断两个数包含的数字相同? 1. 两个数字转换成字符串后:d1,d2 定义两个集合ts1,ts2, 将d1,d2的各位数都添加到集合ts1中 将d1的各位数添加到集合ts2中 最后这个两个集合相等,则,这个两个数包含相同的数字 2.

欧拉工程第63题:Powerful digit counts

题目链接 这个题目有点坑: 先说自己的思路<虽然走不通> 根据题意可知道: a的b次方 除以 最小的b位数(如:10,100,1000) 的商 在 1--9之间,则:a的b次方就是符合题意的 然后就根据这个遍历 先找到第一个数符合条件的数firstnum 再找到第一个符合条件之后的第一个不满足条件的数nextnum 则:这中间有 nextnum - firstnum个数 当b也就是次方数大于18的时候,Long都溢出了 此时:有38个数

欧拉工程第58题:Spiral primes

题目链接 Java程序 package projecteuler51to60; import java.math.BigInteger; import java.util.Iterator; import java.util.Set; import java.util.TreeSet; class level58{ void solve0(){ /*** i = 1 (2i-1)^2-4(i-1) (2i-1)^2-6(i-1) ---------------- ----------------