在几个层面上,这是一个有趣的问题,但有一些问题需要指出。首先,nhgrif 发布的算法是正确的(因此被接受),但请记住,对于给定的“product”函数,“int”和“long”返回值都很快溢出,所以代码实际上从来没有给出 k = 25 的正确答案。事实上,对于 int 类型,上述算法只给出 k = 7 的正确答案,即 1838865600(在我的机器上)。之后,对于 k >= 8,数值不正确。
这可以通过运行 nhgrif 的算法来看到,其中 prod() 函数的输出显示为 up k = 10:
i = 1: -5
i = 2: -60
i = 3: -1140
i = 4: -29640
i = 5: -978120
i = 6: -39124800
i = 7: -1838865600
i = 8: -2147483648
i = 9: -2147483648
i = 10: -2147483648
.
.
.
从上面我们看到 int 的最大值(以大小为单位)在 i = 8 时很快达到,可以通过运行来检查:
#include <iostream>
#include <limits>
int main(int argc, const char * argv[])
{
int maxInt = std::numeric_limits<int>::max();
std::cout << "max: " << maxInt << std::endl;
return 0;
}
给出期望值:
max: 2147483647
我们还看到,对于 long 数据类型,我们有同样的问题,但可以将其增加到 k = 12,直到 long 的限制达到 k = 13,即:-9223372036854775808。
最重要的是,上面发布的代码对 Matt 最初要求的 k = 25 的值给出了错误的答案。
解决方案是对数字使用字符串表示。这种字符串表示通常用于超出普通数据类型限制的大量数字(例如,魔方的# of Rubik's cube states 或一克碳中的原子# of atom)。但我认为这可能需要一些思考,因为计算需要表示为对字符串的操作,以避免直接处理整数和长整数。
有趣的是,Matt 给出的函数直接求和为任意 k 的闭合解:
用 Gamma 函数表示,这需要在 C++ 中定义一些额外的代码(但 C++ 11 已经定义了它)。
作为参考,对于 k = 25,Matt 的 prod() 函数的答案是:-6472463290438308956636841782995191201792000000
对于它的价值,您还可以递归地编写算法:
#include <iostream>
long prod(int k);
int main(int argc, const char * argv[])
{
int k = 10;
for (int i = 1; i <= k; i++) {
std::cout << "i = " << i << ": " << -prod(i) << std::endl;
}
return 0;
}
long prod(int k) {
if (k == 1) {
return 5;
}
else {
return (7*k - 2)*prod(k - 1);
}
}
但是这段代码也有上面讨论的同样的溢出问题。