题目40:找出这个无理数的小数部分的第n位
Champernowne's constantAn 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.
Ifrepresents the nth digit of the fractional part, find the value of the following expression.
题目:
将正整数连接起来可以得到一个无理小数:
0.123456789101112131415161718192021...
可以看出小数部分的第 12 位是 1。
如果用表示这个数小数部分的第 n 位,找出如下表达式的值:
210。。不知道对否
#include <iostream>
using namespace std;
//获取一个int类型的位数
int get(int n)
{
if(n==0) return 1;
int m = 0;
while (n)
{
n/=10;
m++;
}
return m;
}
//获取一个数的第几位
//从左边开始第几个
intgetnum(int n,int m)
{
int k = get(n)-m+1; //就是右边的k个
int z = 1;
while (n)
{
if(z==k)
return n%10;
n/=10;
z++;
}
}
int main(void)
{
int j=0;//第几位
int z = 0;
int result = 1;
for (int i =1;i<1000000;i++)
{
z=get(i);
for (int k=j+1;k<=j+z;k++)
{
if(k==10 || 100==k || 1000==k || 10000==k || 100000==k|| 1000000==k)
{
result*=getnum(i,k-j);
}
}
j+=z;
}
std::cout<<result;
return 0;
} str_1 = '0'
for i in range(1,1000000):
str_1 += str(i)
str_2 = '1'
count = 1
for i in range(7):
count *= int(str_1)
str_2 += '0'
print(count)
结果210 210
def getstr(n):
strlist = '1'
for i in range(2,n+1):
strlist += str(i)
return strlist
strlist = getstr(200000)
cal = 1
for j in range(7):
cal *= int(strlist)
print (cal) # encoding:utf-8
# 小数后第N位相乘
from time import time
def euler040():
s_tmp = '.'
result = 1
for i in range(1,200000):
s_tmp += str(i)
if len(s_tmp) > 1000000:
break
for i in range(0,7):
result *= int(s_tmp)
print(result)
if __name__ == '__main__':
start = time()
euler040()
print('cost %.6f sec' % (time() - start))
210
cost 0.120103 sec 大神们大部分都是遍历1000000
我觉得先分析了一波ps输出格式抄袭了渡风大神一波,前面很多题也感谢渡风大神给我的灵感
此代码使用matlab编程
该问题所用时间为0.007945秒
该问题的答案为210
function Output = champernownesConstant_40(Input)
tic
if nargin == 0
Input = ;
end
%想找到各个位置上的数字,不用全部写出来,只需要计算位数就可以
%个位数1-9,十位数10-99,百位数100-999,千位数1000-9999,万位数10000-99999,十万位数100000-999999
%上述的数字个数一共是9+90*2+900*3+9000*4+90000*5+100000*6 = 1088889位数
%先判断出Input中的数是属于哪两个位数之间的,然后根据低位数的第几个判断出来第几个数
%第一位和第十位都是1
list = ;
Num = 1;
for ii = 1:length(Input)
s = find(list>Input(ii));
%s(1) - 1 =
a = floor((Input(s(1)-1) - list(s(1)-1))/s(1));%低位数的第几个数-1
b = mod((Input(s(1)-1) - list(s(1)-1)),s(1));
qianshu = a + 10^(ii) - 1;
if b == 0
res = num2str(qianshu);
Num = Num * str2num(res(end));
else
zhenshu = qianshu + 1;
res = num2str(zhenshu);
Num = Num * str2num(res(b));
end
end
Output = Num;
toc
disp('此代码使用matlab编程')
disp(['该问题所用时间为',num2str(toc),'秒'])
disp(['该问题的答案为',num2str(Output)])
loadinggg 发表于 2017-5-21 22:12
大神们大部分都是遍历1000000
我觉得先分析了一波ps输出格式抄袭了渡风大神一波,前面很多题也感谢渡风大 ...
感觉招式被偷了{:5_90:} 此代码使用matlab编程
Problem40所用时间为0.0063565秒
Problem40的答案为210
编程思路与楼上一致。
%% Problem40.m
%最后编辑时间:2017-06-12 19:11 版本1.0
%将正整数连接起来可以得到一个无理小数: 0.123456789101112131415161718192021...
%求第1,10,100,1000,10000,100000,1000000,的乘积
function Output = Problem40()
tic
boundary = .*;
boundary = cumsum(boundary); %找出位数的边界
Set = ;
Output = 1;
for ii = 1:6
Temp = Set(ii);
for jj = 1:length(Set)
if boundary(jj) < Temp && Temp <= boundary(jj+1) %预测在哪个位置
Start = jj;
break
end
end
Distance = Set(ii) - boundary(Start);
Num = floor(Distance / (Start + 1));
Numset = mod(Distance,Start + 1);
All= 10^Start : 10^(Start + 1);
if Numset == 0
Exact = num2str(All(Num));
Output = Output * str2double(Exact(end));
else
Exact = num2str(All(Num+1));
Output = Output * str2double(Exact(Numset));
end
end
toc
disp('此代码使用matlab编程')
disp(['Problem40所用时间为',num2str(toc),'秒'])
disp(['Problem40的答案为',num2str(Output)])
end
strTemp = ""
for i in range(1, 200000):
strTemp += str(i)
product = 1
for n in :
product *= int(strTemp)
print(product)
210 结果是:210
用时:0.2652017 秒
import functools
import time
def get_str(num):
count = 0
tmp = 0
while count < num:
tmp += 1
count += len(str(tmp))
return str(tmp)
print("结果是:{}\n用时:{} 秒".format(
functools.reduce(lambda x, y: x*y, )]),
time.process_time())) 本帖最后由 永恒的蓝色梦想 于 2021-3-6 12:39 编辑
ZERO_ACSII = ord('0')
func = lambda x : ord(digits) - ZERO_ACSII
digits =
i = 1
while len(digits) <= 1000000:
digits += str(i)
i += 1
print(func(1) * func(10) * func(100) * func(1000) * func(10000) * func(100000) * func(1000000)) 210
Process returned 0 (0x0) execution time : 0.034 s
Press any key to continue.
参考了6#的解法,先确定每个位数所在的自然数区间,再求出偏移量,取余可以确定具体取那一位
位数和通项公式
https://wx3.sinaimg.cn/mw690/0081qlg6ly1ghltrk2iujj30nm00swea.jpg
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
const int dgt[] = {0,9,189,2889,38889,488889,5888889};//0为占位符
const int M = 1000000;
int extract(int x,int digit){
vector<int> v;
while(x){
v.push_back(x % 10);
x /= 10;
}
int n = v.size();
return v;
}
int main(){
int ans = 1;
for (int i = 10;i <= M;i*=10){
int cur_dgt;
for (int j = 1;j < 6;j++)
if (i > dgt && i < dgt) {cur_dgt = j+1; break;}//落在哪一区间
int t = i - dgt - 1;
int cnt = t / cur_dgt;//偏移了cnt个数
int resd = t % cur_dgt;//取该数的第几位
int tar = i/10 + cnt;//目标数
//printf("%d %d %d %d %d\n",t,cur_dgt,cnt,tar,resd);
ans *= extract(tar,resd);
}
cout << ans << endl;
return 0;
}
1000005 185186
1 1 5 3 7 2 1
210
n = ''
a = 1
while len(n) < 1000001:
n += str(a)
a += 1
print(len(n),a)
print(int(n) , int(n) , int(n) , int(n),int(n) ,int(n) , int(n))
print(int(n) * int(n) * int(n) * int(n) * int(n) * int(n) * int(n)) #include <stdio.h>
#include <string.h>
main()
{
char str, temp;
int i = 1, count = 1;
str = '1';
str = '\0';
for (i = 2; i < 1000000; i++)
{
if (count >= 1000000)
{
break;
}
sprintf(temp, "%d", i);
count += strlen(temp);
strcat(str, temp);
}
count = 1;
for (i = 1; i < 1000001; i *= 10)
{
printf("%c ", str);
count *= (str - '0');
}
printf("\n%d\n", count);
}
210 #找出这个无理数的小数部分的第n位
from time import *
#简单计算得出当数字在19万以内 位数超过百万
def d(n):
str1 = ''
num = 1
while True:
str1 += str(num)
num += 1
if num == 190000:
break
returnint(str1)
#计算
start = time()
n = 1
result = 1
while n:
result *= d(n)
n *= 10
if n == 1000000:
break
end = time()
print(result)
print("用时:%.4f秒" % (end-start))
本帖最后由 guosl 于 2022-1-6 21:18 编辑
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
int f[] = { 0,9,2 * 90,3 * 900,4 * 9000,5 * 90000,6 * 900000 };//f记录i位数的个数
int g[] = { 0,1,10,100,1000,10000,100000 };//记录i位数的第一个数
int getDigit(int k)
{
int nCount = 0, i;
for (i = 1; i <= 6; ++i)//找出k是几位数
{
if (nCount + f >= k)
break;
nCount += f;
}
k -= nCount;//计算k在i位数中的位置
int n = g + k / i - 1, m = k % i;//计算出具体的数
//输出具体的数字
char str;
int nL;
if (m == 0)
{
_itoa_s(n, str, 10);
nL = strlen(str);
}
else
{
_itoa_s(n + 1, str, 10);
nL = m;
}
return int(str - 48);
}
int main(void)
{
int p = getDigit(1);
p *= getDigit(10);
p *= getDigit(100);
p *= getDigit(1000);
p *= getDigit(10000);
p *= getDigit(100000);
p *= getDigit(1000000);
cout << p << endl;
return 0;
} import time as t
start = t.perf_counter()
d_n = ''
for i in range(185186):
d_n += str(i)
product = 1
for j in range(7):
print('d_%d = %s' % (10 ** j, d_n))
product *= int(d_n)
print(product)
print("It costs %f s" % (t.perf_counter() - start))
d_1 = 1
d_10 = 1
d_100 = 5
d_1000 = 3
d_10000 = 7
d_100000 = 2
d_1000000 = 1
210
It costs 0.067895 s $ time ./main
210
real 0m0.001s
user 0m0.000s
sys 0m0.001s
// count bits before 10^l
fn cb(l: u32) -> u32 {
if l == 0 {
return 0;
}
9 * 10u32.pow(l - 1) * l + cb(l - 1)
}
// 返回第i位所在的数字以及偏移量
fn b2n(x: u32) -> (u32, u32) {
let mut base_l = 1;
while cb(base_l) < x {
base_l += 1;
}
base_l -= 1;
(
(x - cb(base_l)) / (base_l + 1) + 10u32.pow(base_l) - 1,
(x - cb(base_l)) % (base_l + 1),
)
}
fn d(x: u32) -> u32 {
let (b, mut i) = b2n(x);
if i == 0 {
return b % 10;
}
let mut y = b + 1;
i = y.ilog10() + 2 - i;
let mut r = 0;
while i > 0 {
r = y % 10;
y /= 10;
i -= 1;
}
r
}
fn main() {
println!("{}", (0..=6).map(|x| d(10u32.pow(x))).product::<u32>())
}
测试
#
mod tests {
use super::*;
#
fn test_cb() {
assert_eq!(cb(1), 9);
assert_eq!(cb(2), 189);
}
#
fn test_b2n() {
assert_eq!(b2n(8), (8, 0));
assert_eq!(b2n(9), (9, 0));
assert_eq!(b2n(100), (54, 1));
assert_eq!(b2n(189), (99, 0));
assert_eq!(b2n(191), (99, 2));
assert_eq!(b2n(192), (100, 0));
}
#
fn test_d() {
assert_eq!(d(1), 1);
assert_eq!(d(12), 1);
assert_eq!(d(13), 1);
assert_eq!(d(100), 5);
}
}
页:
[1]