相当晚才参加派对,但无论如何,这是我的解决方案。很抱歉它是用 Python 而不是 C++ 写的,但应该相对容易翻译。因为这主要是一个算法问题,希望这样可以。至于溢出问题,我能想到的唯一办法就是使用数字数组而不是实际数字。考虑到这个算法,我希望它不会影响性能太多。
https://gist.github.com/frnhr/7608873
它使用了我通过观察和探索问题找到的这三种递归方式。与其试图想出一些晦涩难懂的通用方程式,这里提供了三个例子。从中很容易看出一般情况。
关系1
将具有任意参数的函数调用减少为几个具有更可预测参数的递归调用,以便在关系2和3中使用。
foo(3456) == foo(3000)
+ foo(400) + 400 * (3)
+ foo(50) + 50 * (3 + 4)
+ foo(6) + 6 * (3 + 4 + 5)
关系 2
将形式为L*10^M
(例如:30、7000、900000)的带参数调用简化为可用于关系 3 的递归调用。这些 三角形数 出现得很突然(但是很受欢迎):)
triangular_numbers = [0, 1, 3, 6, 10, 15, 21, 28, 36]
foo(3000) == 3 * foo(1000) + triangular_numbers[3 - 1] * 1000
只有当
L > 1
时才有用。对于
L = 1
,它是显然的。在这种情况下,直接转到关系3。
关系3:递归地将参数格式为
1*10^M
的调用缩小到参数被除以10的调用。
foo(1000) == foo(100) * 10 + 44 * 100 + 100 - 9 # 44 and 9 are constants
最终你只需要真正计算0到10的数字的和或数字,结果只需要进行3次这样的计算。其他所有事情都可以通过递归来处理。我相当确定它在O(logN)时间内运行。那真是太快了!!!在我的笔记本电脑上,它可以在不到7秒的时间内计算出给定数字的超过1300位数的数字总和!你的测试(1000000000000000000)在0.000112057秒内被计算出来!