各个数位都不含9的所有8位数的倒数和是多少

MATLAB的:function f = anysum(n)a = 1:8; b = 0:8;for i = 2:n b = b / 10; a = bsxfun(@plus,a(:),b);endf = sum(b(2)./a(:));\u0026gt;\u0026gt; timeit(@()anysum(8))ans = 0.190502222094876@云天明 :本来是这样的:function f = anysum(n)a = 1:8; b = 0:8;for i = 2:n a = bsxfun(@plus,10*a(:),b);endf = sum(1./a(:));这个应该应该比较好懂,只要理解bsxfun的作用应该能看出来这里每一步是求出所有不含有9的i位数。例如第一次循环(i=2),10*a(:)就是 (10:10:80)\u0026#39;,从而:\u0026gt;\u0026gt; bsxfun(@plus,(10:10:80)\u0026#39;,0:8)ans = 10 11 12 13 14 15 16 17 18 20 21 22 23 24 25 26 27 28 30 31 32 33 34 35 36 37 38 40 41 42 43 44 45 46 47 48 50 51 52 53 54 55 56 57 58 60 61 62 63 64 65 66 67 68 70 71 72 73 74 75 76 77 78 80 81 82 83 84 85 86 87 88所以循环最终求得的就是所有不含有9的n为数字,最后求倒数和就是结果你说看不懂的那个版本只是把每次的10*a(:)变成了b/10; 因为显然a的元素个数要比b(只有9个元素)多很多,所以这样修改可以减少计算量而这样计算的过只是和本来计算的结果相比缩小了10^(n-1)倍,所以最终求倒数的时候将分母1也缩小10^(n-1)倍,而b(2)恰好就是10^(n-1),所以就用b(2)做分母了由于浮点数计算误差这样修改会导致结果和原来的结果稍有不同,不过毕竟原来的算法本身也存在误差,所以修改导致的误差在可以接受范围内
■网友
我过来卖个萌结果是 11.074 seconds (149 M allocations: 3070 MB, 3.72% gc time)1.0714523172876622Julia 卖萌用代码function sss (x, n) (n==0)?1/x: mapfoldr( t-\u0026gt;sss(x+t*10^(n-1), n-1),+, ) endmapfoldr( x-\u0026gt;sss(x*10^7, 7),+,)
■网友
谢邀,这个计算对精度要求应该挺高的,既然要求不包含9,那么用九进制做枚举就可以了。9^8 = 43046721,还可以接受,求倒数感觉没有什么太好的直接计算的方法,求近似似乎还可以快。
■网友
我有许多思路,我只是想想。
计算机最擅长的是二进制,如果能够通过若干次二进制运算就能判断一个数字是否含9就太好了。
没有必要纠结八位数,把眼界放的宽一点:判断一个32位的无符号int是否包含9。

形式化一下这个问题
输入为32个布尔值,输出为一个布尔值。
各个数位都不含9的所有8位数的倒数和是多少

可以采用的运算只能为and,or,not,问最少使用多少个基本运算才能拼凑出一个f来。

这个问题规模很大。卡诺图化简布尔表达式需要枚举的变量有点太多了,但是一旦化简之后得到的结果会很有用。如果不要求精确解,使用决策树,每个结点分开两个叉,每个结点从若干个操作中选择一个(操作指and,or,not)。最终在得到的决策树就是一个f。也许这个问题是有规律的,可以先试试1到8位的f各是什么形式。这个可以暴力实现,相当于搜索问题。使用and,or,not操作太多,可以使用与非、或非(这两个操作符可以替换掉and,or,not)。训练一个神经网络,输入32位,相当于二分类问题。但是仅仅是好玩,复杂度肯定很高。这个问题可能是一个NP问题,如果那样的话,就可以给自己胡编乱整找到充足理由了。如果判断一个整数是不是9的倍数,会非常容易:使用有限状态自动机(有9个结点,每个结点有两个出度),直接对此DFA使用布尔表达式来描述即可。此问题能否也这么做呢?


推荐阅读