Project Euler Problem 64 (C++和Python)

本文深入探讨了所有平方根在连续分数表示下呈现的周期性规律,并通过C++及Python代码实现了对N≤10000范围内具有奇数周期的连续分数数量的计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem 64 : Odd period square roots

All square roots are periodic when written as continued fractions and can be written in the form:
在这里插入图片描述
It can be seen that the sequence is repeating. For conciseness, we use the notation √23 = [4;(1,3,1,8)], to indicate that the block (1,3,1,8) repeats indefinitely.

The first ten continued fraction representations of (irrational) square roots are:

√2=[1;(2)], period=1
√3=[1;(1,2)], period=2
√5=[2;(4)], period=1
√6=[2;(2,4)], period=2
√7=[2;(1,1,1,4)], period=4
√8=[2;(1,4)], period=2
√10=[3;(6)], period=1
√11=[3;(3,6)], period=2
√12= [3;(2,6)], period=2
√13=[3;(1,1,1,1,6)], period=5

Exactly four continued fractions, for N ≤ 13, have an odd period.

How many continued fractions for N ≤ 10000 have an odd period?

C++代码

#include <iostream>
#include <vector>
#include <iterator>
#include <cmath>
#include <cassert>

using namespace std;

//#define UNIT_TEST

class PE0064
{
private:
    int getPeriod(int N);

public:
    int getNumOfContinuedFractions(int maxN);
};

int PE0064::getPeriod(int N)
{
#ifdef UNIT_TEST
    vector<int>fractions_vec;
#endif
    int period = 0;
    int m = 0, d = 1;
    double root = sqrt((double)N);
    int a0 = int(root);
    int a = a0;

#ifdef UNIT_TEST
    fractions_vec.push_back(a0);
    // cout << "m=" << m << ", d=" << d << ", a=" << a << endl;
#endif

    while (a != 2*a0)
    {
        m = a*d - m;
        d = (N - m*m) / d;
        a = int((root + m) / d);
        period++;

#ifdef UNIT_TEST
        fractions_vec.push_back(a);
        //cout << "m=" << m << ", d=" << d << ", a=" << a << endl;
#endif
    }

#ifdef UNIT_TEST
    cout << "√" << N << " = [" << fractions_vec[0] << "; (" ;
    copy(fractions_vec.begin()+1, fractions_vec.end()-1, 
         ostream_iterator<int>(cout, ","));
    int size = fractions_vec.size();
    cout << fractions_vec[size-1] << ")], period = " << period << endl;
#endif

    return period;
}

int PE0064::getNumOfContinuedFractions(int maxN)
{
    int numOfContinuedFractions = 0;
    
    for (int N=2; N<=maxN; N++)
    {
        int root = (int)sqrt(double(N));;
        if (root*root == N)
        {
            continue;
        }
        else
        {
            if (getPeriod(N) % 2 == 1)
            {
                numOfContinuedFractions ++;
            }
        }
    }

    return numOfContinuedFractions;
}
    
int main()
{
    PE0064 pe0064;

    assert(4 == pe0064.getNumOfContinuedFractions(13));

    cout << pe0064.getNumOfContinuedFractions(10000);
    cout << " continued fractions for N<=10000 have an odd period." << endl;

    return 0;
}

Python代码

def getPeriod(N):
    global Enable_Debug
    period, m, d = 0, 0, 1
    root = int(N**0.5)
    a0, a = root, root
    fractions_list = [ a0 ]

    #print("m=", m, ", d=", d, ", a=", a)

    while a != 2*a0:
        m = a*d - m
        d = (N - m*m) / d
        a = int((root + m) / d)
        period += 1

        fractions_list += [ a ]
        #print("m=", m, ", d=", d, ", a=", a)

    if True == Enable_Debug:
        print("√%d"% N, "= [%d" % fractions_list[0], "; (", end='')
        for f in fractions_list:
            if f != fractions_list[-1]:
                print("%d, " %f, end='')
            else:
                print("%d" %f, end='')
        print(")], period = %d" % period)

    return period

def getNumOfContinuedFractions(maxN):
    numOfContinuedFractions = 0
    
    for N in range(2, maxN+1):
        root = int(N**0.5)
        if root*root == N:
            continue
        else:
            if 1 == getPeriod(N) % 2:
                numOfContinuedFractions += 1

    return numOfContinuedFractions
        
def main():
    global Enable_Debug
    
    Enable_Debug = True
    assert 4 == getNumOfContinuedFractions(13)

    Enable_Debug = False
    print(getNumOfContinuedFractions(10000), end=' ')
    print("continued fractions for N<=10000 have an odd period.")

if  __name__ == '__main__':
    main()

Python 代码(类的实现)

class PE0064(object):
    def __init__(self):
        self.Enable_Debug = True

    def getPeriod(self, N):
        period, m, d = 0, 0, 1
        root = int(N**0.5)
        a0, a = root, root
        fractions_list = [ a0 ]

        #print("m=", m, ", d=", d, ", a=", a)

        while a != 2*a0:
            m = a*d - m
            d = (N - m*m) / d
            a = int((root + m) / d)
            period += 1

            fractions_list += [ a ]
            #print("m=", m, ", d=", d, ", a=", a)

        if True == self.Enable_Debug:
            print("√%d"% N, "= [%d" % fractions_list[0], "; (", end='')
            for f in fractions_list:
                if f != fractions_list[-1]:
                    print("%d, " %f, end='')
                else:
                    print("%d" %f, end='')
            print(")], period = %d" % period)

        return period

    def getNumOfContinuedFractions(self, maxN):
        numOfContinuedFractions = 0
        
        for N in range(2, maxN+1):
            root = int(N**0.5)
            if root*root == N:
                continue
            else:
                if 1 == self.getPeriod(N) % 2:
                    numOfContinuedFractions += 1

        return numOfContinuedFractions
    
def main():
    pe0064 = PE0064()
    assert 4 == pe0064.getNumOfContinuedFractions(13)

    pe0064.Enable_Debug = False
    print(pe0064.getNumOfContinuedFractions(10000), end=' ')
    print("continued fractions for N<=10000 have an odd period.")

if  __name__ == '__main__':
    main()
 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值