[..]从n×n个网格的左上角至右下角 [..]
您的代码并不反映:
// ...
if (x == n || y == 0)
return current_sum;
// ...
想想一条完全水平的路径。例如,在2对3网格中,当索引以0
开始,左下角为(0 | 0)
时,则右下角将为(1 | 0)
。现在考虑右上角,这是(1 | 2)
。上述两个条件都不适用于这些值,因此您可以总结下两个单元的递归调用:(2 | 2)
(向右)和(1 | 1)
(向下)。
第一个单元格(右转)是问题:在那里,x == 2 == n
因此您返回的路径总数为,尽管它没有在右下角结束。因此,你总结了太多路径,导致整体总和过大。
我想这应该这样做:
unsigned sum_inner(
unsigned const accumulatedSum,
size_t const x, size_t const y,
size_t const gridSideSize) {
bool atRightEdge = (x == gridSideSize - 1);
bool atBottomEdge = (y == 0);
if (atRightEdge && atBottomEdge) {
// Awesome, in lower right corner, so everything is fine
// Except that with the implementation of the other two edge cases, this
// will never be run (except for the 1x1 case)!
printf("reached lower right edge!\n");
return accumulatedSum + 1;
} else if (atRightEdge) {
// Right edge, so from here one can only go down. Since there's only one
// possible path left, sum it directly:
return accumulatedSum + y + 1;
} else if (atBottomEdge) {
// Bottom edge, so from here one can only go right. Since there's only one
// possible path left, sum it directly:
return accumulatedSum + (gridSideSize - x) + 1;
} else {
// Somewhere in the grid, recursion time!
return sum_inner(accumulatedSum + y, x + 1, y, gridSideSize) +
sum_inner(accumulatedSum, x, y - 1, gridSideSize);
}
}
unsigned sum_monotonic_tl_br(size_t const gridSideSize) {
return sum_inner(0, 0, gridSideSize - 1, gridSideSize);
}
(Live with sizes from 1 to 15)
我认为加上与输入一个具体的例子,预期和实际产量将有很大的帮助。 –
这是欧拉工程的一个问题:https://projecteuler.net/problem=15 – jforberg
重点关注回报。 x + 1,y-1。如何使用2步循环,x从低到高,y从高到低移动?它可以解决移动到零价值的问题。 –