Project Euler:Problem 65 Convergents of e

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;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值