这是来自hackerrank的问题;我试图理解递归是如何工作的。
手头的任务是:
找出可以表达给定整数 X 的方式的数量 作为独特自然数的 N 次幂的总和。
例如,如果 X = 100 且 N = 2
100 =10²=6²+8²=1²+3²+4²+5²+7²
所以100可以表示为3中唯一自然数的平方 不同的方式,所以我们的输出是3。
这是我的代码:
#include <cmath>
#include <iostream>
using namespace std;
int numOfSums(int x, int& n, const int k) {
int count = 0, j;
for (int i = (k + 1); (j = (int) pow(i, n)) <= x; i++) {
j = x - j;
if (j == 0)
count++;
else
count += numOfSums(j, n, i);
}
return count;
}
int main() {
int x, n;
cin >> x >> n;
cout << numOfSums(x, n, 0) << endl;
return 0;
}
但是当我输入x = 100和n = 2时,它输出的是2
,而不是3
。代码有什么问题?
答案 0 :(得分:0)
当我使用此3
运行它时,您的示例代码会返回main()
:
#include <iostream>
int main() {
int x = 100, n = 2;
cout << numOfSums(x, n, 0) << endl;
return 0;
}
问题很可能是你正在使用double std::pow(double, int)
,但是你没有将结果四舍五入到最接近的整数((int)
向下舍入)。你应该在截断之前添加½:
j = static_cast<int>(pow(i, n) + 0.5)
我使用了更多C ++风格的演员,我觉得更清楚。
实现对整数进行操作的等效std::pow()
会更有效。如果你想要,那也可以是递归的:
unsigned long pow(unsigned long x, unsigned long n)
{
return n ? x * pow(x, n-1) : 1;
}
迭代版本更有效(或尾递归版本和合适的优化编译器)。
缩减版本,我的更改:
template<typename T>
T powi(T x, T n)
{
T r{1};
for (; n; n /= 2) {
r *= n%2 ? x : 1;
x *= x;
}
return r;
}
template<typename T>
T numOfSums(T x, T n, T i = {})
{
T count{}, j;
for (++i; (j = powi(i, n)) <= x; ++i)
count += j == x ? 1 : numOfSums(x-j, n, i);
return count;
}
#include <iostream>
int main()
{
unsigned long int x = 100, n = 2;
std::cout << numOfSums(x, n) << std::endl;
return 0;
}