我的目标是找到4到666554之间的所有数字的总和,仅包括4,5,6.
SUM = 4+5+6+44+45+46+54+55+56+64+65+66+.....................+666554.
Run Code Online (Sandbox Code Playgroud)
简单的方法是运行循环并仅添加由4,5和6组成的数字.
long long sum = 0;
for(int i=4;i <=666554;i++){
/*check if number contains only 4,5 and 6.
if condition is true then add the number to the sum*/
}
Run Code Online (Sandbox Code Playgroud)
但它似乎效率低下.检查数字是由4,5和6组成需要时间.有没有办法提高效率.我已经尝试了很多,但没有找到新的方法.请帮助.
Yu *_*Hao 46
对于1位数字,请注意
4 + 5 + 6 == 5 * 3
Run Code Online (Sandbox Code Playgroud)
对于2位数字:
(44 + 45 + 46) + (54 + 55 + 56) + (64 + 65 + 66)
== 45 * 3 + 55 * 3 + 65 * 3
== 55 * 9
Run Code Online (Sandbox Code Playgroud)
等等.
在一般情况下,n-digits数字,有3 ň的其中包括4,5,6只是,他们的平均价值是完全5...5(n位).使用代码,它们的总和是('5' * n).to_i * 3 ** n(Ruby)或int('5' * n) * 3 ** n(Python).
您计算最多6位数字,然后减去666555to 的总和666666.
PS:对于小数字666554,使用模式匹配足够快.(例子)
在基数3(数字值的数量)中实现一个计数器,例如0,1,2,10,11,12,20,21,22,100 ....然后将基数为3的数字转换成数字为4的小数,5,6(0-> 4,1-> 5,2-> 6),并添加到运行总计.重复直到极限.
def compute_sum(digits, max_val):
def _next_val(cur_val):
for pos in range(len(cur_val)):
cur_val[pos]+=1
if cur_val[pos]<len(digits):
return
cur_val[pos]=0
cur_val.append(0)
def _get_val(cur_val):
digit_val=1
num_val=0
for x in cur_val:
num_val+=digits[x]*digit_val
digit_val*=10
return num_val
cur_val=[]
sum=0
while(True):
_next_val(cur_val)
num_val=_get_val(cur_val)
if num_val>max_val:
break
sum+=num_val
return sum
def main():
digits=[4,5,6]
max_val=666554
print(digits, max_val)
print(compute_sum(digits, max_val))
Run Code Online (Sandbox Code Playgroud)
数学是好的,但并非所有的问题都是"可压缩的",所以知道如何在没有数学的情况下处理它们是值得的.
在这个问题中,求和是微不足道的,难以有效地枚举需要添加的数字,乍一看.
"过滤"路径是一种可能性:逐步生成所有可能的数字,并过滤掉那些不匹配的数字; 但它的效率也很低(一般来说):
因此,我建议采用"世代"方法:只生成符合条件的数字(以及所有数字).
我会注意到,生成由4,5和6组成的所有数字就像计数(三元组):
让我们在Python中作为生成器:
def generator():
def convert(array):
i = 0
for e in array:
i *= 10
i += e
return i
def increment(array):
result = []
carry = True
for e in array[::-1]:
if carry:
e += 1
carry = False
if e > 6:
e = 4
carry = True
result = [e,] + result
if carry:
result = [4,] + result
return result
array = [4]
while True:
num = convert(array)
if num > 666554: break
yield num
array = increment(array)
Run Code Online (Sandbox Code Playgroud)
其结果可以打印sum(generator()):
$ time python example.py
409632209
python example.py 0.03s user 0.00s system 82% cpu 0.043 total
Run Code Online (Sandbox Code Playgroud)