zoukankan      html  css  js  c++  java
  • [Project Euler] Problem 57

    Problem Description

    It is possible to show that the square root of two can be expressed as an infinite continued fraction.

    sqrt(2) = 1 + 1/(2 + 1/(2 + 1/(2 + ... ))) = 1.414213...

    By expanding this for the first four iterations, we get:

    1 + 1/2 = 3/2 = 1.5
    1 + 1/(2 + 1/2) = 7/5 = 1.4
    1 + 1/(2 + 1/(2 + 1/2)) = 17/12 = 1.41666...
    1 + 1/(2 + 1/(2 + 1/(2 + 1/2))) = 41/29 = 1.41379...

    The next three expansions are 99/70, 239/169, and 577/408, but the eighth expansion, 1393/985, is the first example where the number of digits in the numerator exceeds the number of digits in the denominator.

    In the first one-thousand expansions, how many fractions contain a numerator with more digits than denominator?

    C++

    Get the pseudo-code of calculating the numerator and denominator of the fraciton first from the expression above. Then you could easily write the main code:

    Main()

    void Problem_57()
    {
        int count = 0;
        for(int i=1; i<= EXPANSION_TIME; i++)
        {
            Fraction fra(1, 2);
            int loop = 1;
            while(loop <i)
            {
                fra.Add(2);
                fra.Reciprocal();
                loop++;
            }
            fra.Add(1);
    
            if(fra.IsOKForProblem())
            {
                count++;
                // fra.Display();
            }
        }
        printf("result = %d\n", count);
    }

    You may need a Fraction class which manages two fields numerator and denominator.

    Plealse note that the numbers in the calculation are far beyond the maxnium of a 4 bytes integer, you need a Big Integer type.

    I would like to show my simple implementation below:

    Fraction and BigInteger

    class BigInteger
    {
    public:
        BigInteger(int a)
        {
            memset(m_digits, 0, 1000);
            int index = 0;
            while(a != 0)
            {
                m_digits[index] = a % 10;
                a = a/ 10;
                index++;
            }
    
            m_length = index;
        }    
    
        void Add(const BigInteger& other)
        {
            int maxLength = max(m_length, other.m_length);
            
            for(int i=0; i<maxLength; i++)
            {
                int temp = m_digits[i] + other.m_digits[i];
                if(temp >= 10)
                {
                    m_digits[i+1]++;
                    m_digits[i] = temp % 10;
                }
                else
                {
                    m_digits[i] = temp;
                }
            }
            m_length = (m_digits[maxLength] == 0) ? maxLength : (maxLength + 1);
        }
    
        void Multiply(int num)
        {
            BigInteger other(*this);
            for(int i=0; i<num - 1; i++)
            {
                Add(other);
            }
        }
        int GetLength()
        {
            return m_length;
        }
    
        void Display()
        {
            char str[1000] = {0};
            for(int i = m_length - 1; i>=0; i--)
            {
                str[m_length - i - 1] = (char)(m_digits[i] + '0');
            }
            printf("%s", str);
        }
    private:
        BYTE m_digits[1000];
        int m_length;
    };
    
    class Fraction
    {
    public:
        Fraction(int numerator, int denominator)
            : m_bi1(numerator), m_bi2(denominator), m_isBI1Numerator(true)
        {
    
        }
    
        void Reciprocal()
        {
            m_isBI1Numerator = !m_isBI1Numerator;
        }
    
        void Add(int addend)
        {
            BigInteger temp(GetDenominator());
            temp.Multiply(addend);
            GetNumerator().Add(temp);
        }
    
        void Display()
        {
            GetNumerator().Display();
            printf("/");
            GetDenominator().Display();
            printf("\n");
        }
        
        bool IsOKForProblem()
        {
            return GetNumerator().GetLength() > GetDenominator().GetLength();
        }
    
    private:
        BigInteger& GetNumerator()
        {
            return m_isBI1Numerator ? m_bi1 : m_bi2;
        }
    
        BigInteger& GetDenominator()
        {
            return m_isBI1Numerator ? m_bi2 : m_bi1;
        }
    
        bool m_isBI1Numerator;
        BigInteger m_bi1;
        BigInteger m_bi2;
    };
  • 相关阅读:
    Dapper的常用操作
    git下载慢的解决方案
    笔记
    第06组 Beta冲刺(3/5)
    第06组 Beta冲刺(2/5)
    第06组 Beta冲刺(1/5)
    第06组 Alpha事后诸葛亮
    第06组 Alpha冲刺(6/6)
    第06组 Alpha冲刺(5/6)
    第06组 Alpha冲刺(4/6)
  • 原文地址:https://www.cnblogs.com/quark/p/2624733.html
Copyright © 2011-2022 走看看