您的位置:首页 > 其它

[Project Euler] Problem 57

2012-08-06 10:31 316 查看

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;
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: