您的位置:首页 > 其它

Project Euler:Problem 65 Convergents of e

2015-07-15 14:57 393 查看
The square root of 2 can be written as an infinite continued fraction.

√2 = 1 +1
2 +1
2 +1
2 +1
2 + ...
The infinite continued fraction can be written, √2 = [1;(2)], (2) indicates that 2 repeats ad infinitum. In a similar way, √23 = [4;(1,3,1,8)].
It turns out that the sequence of partial values of continued fractions for square roots provide the best rational approximations. Let us consider the convergents for √2.

1 +1
= 3/2
2
1 +1
= 7/5
2 +1
2
1 +1
= 17/12
2 +1
2 +1
2
1 +1
= 41/29
2 +1
2 +1
2 +1
2
Hence the sequence of the first ten convergents for √2 are:

1, 3/2, 7/5, 17/12, 41/29, 99/70, 239/169, 577/408, 1393/985, 3363/2378, ...
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, 8/3, 11/4, 19/7, 87/32, 106/39, 193/71, 1264/465, 1457/536, ...
The sum of digits in the numerator of the 10th convergent is 1+4+5+7=17.
Find the sum of digits in the numerator of the 100th convergent of the continued fraction for e.

继续找规律。没想到数值会那么大,用到大数乘法和大数加法。

#include <iostream>
#include <string>
using namespace std;

int a[101];

string num2str(int n)
{
	string res = "";
	while (n)
	{
		int tmp = n % 10;
		char c = tmp + '0';
		res = c + res;
		n /= 10;
	}
	return res;
}

string strplus(string a, string b)
{
	string res = "";
	int lena = a.length();
	int lenb = b.length();
	string c;
	int len;
	if (lena > lenb)
	{
		int tmp = lena - lenb;
		c.resize(tmp, '0');
		b = c + b;
		len = lena;
	}
	else
	{
		int tmp = lenb - lena;
		c.resize(tmp, '0');
		a = c + a;
		len = lenb;
	}
	int flag = 0;
	for (int i = len - 1; i >= 0; i--)
	{
		int tp = a[i] + b[i] + flag - '0' - '0';
		flag = tp / 10;
		int tt = tp % 10;
		char c = tt + '0';
		res = c + res;
	}
	if (flag != 0)
		res = '1' + res;
	return res;
}

void reverse_data(string &data)
{
	char temp = '0';
	int start = 0;
	int end = data.size() - 1;

	while (start < end)
	{
		temp = data[start];
		data[start++] = data[end];
		data[end--] = temp;
	}
}

void compute_value(string lhs, string rhs, string &result)
{
	reverse_data(lhs);
	reverse_data(rhs);
	int i = 0, j = 0, res_i = 0;
	int tmp_i = 0;
	int carry = 0;

	for (i = 0; i != lhs.size(); ++i, ++tmp_i)
	{
		res_i = tmp_i;  //在每次计算时,结果存储的位需要增加      
		for (j = 0; j != rhs.size(); ++j)
		{
			carry += (result[res_i] - '0') + (lhs[i] - '0') * (rhs[j] - '0');//此处注意,每次计算并不能保证以前计算结果的进位都消除, 并且以前的计算结果也需考虑。      
			result[res_i++] = (carry % 10 + '0');
			carry /= 10;
		}
		while (carry)//乘数的一次计算完成,可能存在有的进位没有处理      
		{
			result[res_i++] = (carry % 10 + '0');
			carry /= 10;
		}
	}
	for (int i = result.size() - 1; i >= 0; i--)
	{
		if (result[i] != '0')
			break;
		else
			result.pop_back();
	}

	reverse_data(result);
}

void init()
{
	a[1] = 2;
	for (int i = 2; i <= 100; i++)
	{
		if (i % 3 == 0)
			a[i] = i / 3 * 2;
		else
			a[i] = 1;
	}
}

int count_num(string s)
{
	int count = 0;
	for (int i = 0; i < s.length(); i++)
	{
		count += s[i] - '0';
	}
	return count;
}

int main()
{
	memset(a, 0, sizeof(a));
	init();

	string n = num2str(a[100]);
	string d = "1";
	int i = 99;
	while (i)
	{
		string tmp = d;
		string aa = num2str(a[i]);
		string tmp1(aa.length()+d.length(),'0');
		compute_value(aa, d, tmp1);
		d = strplus(n, tmp1);
		n = tmp;
		i--;
	}

	//cout << n << " " << d << endl;
	cout << count_num(d) << endl;
	system("pause");
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: