Project Euler 题解 #40 Champernowne's constant

来源:互联网 发布:淘宝短信回访话术 编辑:程序博客网 时间:2024/06/05 08:38

题目:Champernowne's constant

An irrational decimal fraction is created by concatenating the positive integers:

0.123456789101112131415161718192021...

It can be seen that the 12th digit of the fractional part is 1.

If dn represents the nth digit of the fractional part, find the value of the following expression.

d1 ×d10×d100×d1000×d10000×d100000×d1000000

这个题意是从特定的序列中获取特定的数字,重点在于从序列中分析出特点。

解题思路

1.从数字的位数角度看,有下面的规律:
当数字位数为n位时,所包含的的数字总数为:9×10n-1×n。
例如:n=3,10~99,数字总数为9×10×2=180。
 
2.给定D(Z)时,首先需要知道对应的是数字取至一个几位数。便可以知道数字来自哪个数。
通过第1点可以用加法算出来自N位数。
先算出偏移量offset
那么,来自的数字Y = 10n-1+offset/N。
取数字Y中的第几位数呢?
index = N - offset%N。
 
如何取出数x的第n位数呢?公式如下:
 
具体应用:
求D(100)。
首先可以知道来自一个2位数,N=2。
offset = 100-9-1 = 90
Y = 10+90/2 = 55
index = 2-90%2 = 2
明显Y的第2位为5。
得D(100) = 5。 

代码实现 

//https://projecteuler.net/problem=40//Champernowne's constant#include <iostream>#include <cmath>using namespace std;int GetNthDigit(unsigned int x, unsigned int N){return N <= 0? 0 : (x/(int)pow(10.0, int(N - 1)))%10;}int D(unsigned int x){unsigned int guard = 0;int N = 0;do {++N;guard += 9 * N * (unsigned int)pow(10.0, int(N - 1));} while (x > guard);unsigned int offset = x - 1 - (guard - 9 * N * (unsigned int)pow(10.0, int(N - 1)));unsigned int num = (unsigned int)pow(10.0, int(N - 1)) + offset/N;unsigned int index = N - offset%N;return GetNthDigit(num, index);}int _tmain(int argc, _TCHAR* argv[]){cout<<D(1)<<endl;cout<<D(10)<<endl;cout<<D(100)<<endl;cout<<D(1000)<<endl;cout<<D(10000)<<endl;cout<<D(100000)<<endl;cout<<D(1000000)<<endl;system("pause");return 0;}
输入:
D(1)  = 1
D(10)  = 1
D(100)  = 5
D(1000)  = 3
D(10000)  = 7
D(100000)  = 2
D(1000000)  = 1
连乘可得210。
原创粉丝点击