蛮力是一种非常浪费的方法。我们可以做得更好。
(我为格式道歉;我希望内容仍然足够清晰。)
首先,让我们简化问题:
EvenProductNumbersBetween(RangeStart, RangeEnd) = NumbersBetween(RangeEnd - RangeStart) - AllOddDigitNumbersBetween(RangeStart, RangeEnd)
NumbersBetween(RangeStart, RangeEnd) = (RangeEnd - RangeStart) + 1
AllOddDigitNumbersBetween(RangeStart, RangeEnd) = AllOddDigitNumbersUpTo(RangeEnd) - AllOddDigitNumbersUpTo(RangeStart-1)
现在我们开始了:计算 AllOddDigitNumbersUpTo(RangeEnd)
首先,考虑简单的情况:
(假设 RangeEnd 为正)
如果 RangeEnd 是单个数字(即 < 10),则
AllOddDigitNumbersUpTo(RangeEnd) = Floor((RangeEnd+1)/2)
E.g.:
AllOddDigitNumbersUpTo(0) = {} = 0
AllOddDigitNumbersUpTo(1) = {1} = 1
AllOddDigitNumbersUpTo(2) = {1} = 1
AllOddDigitNumbersUpTo(3) = {1,3} = 2
AllOddDigitNumbersUpTo(4) = {1,3} = 2
AllOddDigitNumbersUpTo(5) = {1,3,5} = 3
AllOddDigitNumbersUpTo(6) = {1,3,5} = 3
AllOddDigitNumbersUpTo(7) = {1,3,5,7} = 4
AllOddDigitNumbersUpTo(8) = {1,3,5,7} = 4
AllOddDigitNumbersUpTo(9) = {1,3,5,7,9} = 5
如果 RangeEnd 可以是具有特定位数的任何数字,则
考虑到每个数字必须有五个奇数之一作为选择(前导零缩短长度,因此被排除在外),所以这很容易直接计算:
AllOddDigitNumbersOfLength(NumberLength) = 5^NumberLength
E.g.:
AllOddDigitNumbersOfLength(1) = {1, 3, 5, 7, 9} = 5
AllOddDigitNumbersOfLength(2) = {1, 3, 5, 7, 9} * {1, 3, 5, 7, 9} = 5*5 = 25
AllOddDigitNumbersOfLength(3) = 5*5*5 = 125
...
否则,将 RangeEnd 分开:
RangeEnd = (FirstDigit * 10^PowerOfFirstDigit) + Remainder
AllOddDigitNumbersUpTo(RangeEnd) = AllOddDigitNumbersUpTo(FirstDigit) * AllOddDigitNumbersOfLength(PowerOfFirstDigit-1) + AllOddDigitNumbersUpTo(Remainder)
不幸的是,前导零有一个复杂的情况。(感谢@AndyProwl 用我的答案的早期版本向我指出了这个问题!)如果余数以零开头,那么我们不应该在最后添加 AllOddDigitNumbersUpTo(Remainder) 项,因为受约束的前导零会使即使我们尝试制造的每一个较小的数字,该产品也是如此。
E.g.:
AllOddDigitNumbersUpTo(6300193) =
= AllOddDigitNumbersUpTo(6*(10^7) + 300193)
= AllOddDigitNumbersUpTo(6) * AllOddDigitNumbersOfLength(7-1) + AllOddDigitNumbersUpTo(300193)
= 3 * 5^6 + AllOddDigitNumbersUpTo(300193)
= Trivial * Trivial + LogarithmicallySmallerCase
AllOddDigitNumbersUpTo(300193) =
= AllOddDigitNumbersUpTo(3*(10^6) + 00193)
= AllOddDigitNumbersUpTo(3) * AllOddDigitNumbersOfLength(6-1)
= 2 * 5^5
= Trivial * Trivial