我有两种对象,Ball
和Platform
。球的坐标为(x,y)
,平台为(x_begin, x_end, y)
。最多可以有80个平台。
我被要求找到任何给定Ball
到地面的最短路径(y=0
)。请注意,此输出应仅为最小距离。
考虑到我认为最好使用蛮力的约束:计算到地面的所有可能距离,然后返回最小值。
我以为我会做的是写一个递归函数:首先计算到最近平台的垂直距离,然后再分支到右边和左边,然后再返回。破裂的条件是所有路径到达地面时。
void calculateDistances(Ball b, vector<Platform> ps, vector<float>* distances)
{
//The idea is to have, for every branch
// distances[i] = vertical distance
// distances[i+1] = distance to right
// distances[i+2] = distance to left
Platform* p = NULL;
float d_y = verticalDistanceToNearestPlatform(ps, p); // "p" now holds the platform the ball is on
if (d_y == 0)
return; //already on floor
distances->push_back(d_y);
d_x_right = distanceToRightEdgeOfPlatform(p);
distances->push_back(d_x_right);
d_x_left = distanceToLeftEdgeOfPlatform(p);
distances->push_back(d_x_left);
}
这里的问题很明显......地球上我怎么做这个递归?
非常感谢!
PS:这个问题意味着在大约两个半小时内解决。
答案 0 :(得分:4)
递归解决方案(比如,horizontalDistanceToGround(x, y)
)将涉及计算从某个任意点(x, y)
到地面最近点的水平距离,如下所示:
(x, y)
与地面之间没有平台,则返回0。(x, y)
与地面之间存在任何平台,则找到最近的此类平台(即最小platform_y
小于y
的平台。如果该平台位于(platform_min_x, platform_max_x, platform_y)
,则返回(x - platform_min_x) + horizontalDistanceToGround(platform_min_x, platform_y)
和(platform_max_x - x) + horizontalDistanceToGround(platform_max_x, platform_y)
的最小值。这基本上计算了从当前x位置到平台末端以及从那里到地面所需的最小距离。我会在(x, y)
和地面(如果有的话)之间找到最近的平台让你弄明白。
球与地之间的最短距离为distanceToGround(ball_x, ball_y) + ball_y
。
注意:根据@ MooingDuck关于垂直距离与递归无关的有用评论进行了更新。
答案 1 :(得分:2)
您可以将此问题转换为图形问题,然后使用任意数量的图形搜索算法来解决它。
为此,循环遍历所有平台并为其每个边以及直接位于另一个平台边缘下方的任何点创建节点。将共享共同平台的所有节点连接在一起。也可以建立垂直连接。
对地面执行相同的操作,但不要为边缘添加额外的节点,也不要连接地面节点
现在,您可以使用Dijkstra的算法(重建变体)在图表中搜索顶部和底部每个点之间的最短路径。选择具有最低值的结果,您就完成了。 Dijkstra的算法在O(N ^ 2)中运行,其中N是节点,用于天真实现,O(E + N log N),其中E是智能实现的边缘。
您也可以使用A *,这可能更容易实现。
搜索看看球从边缘掉下来的平台很容易。把地面当作一个平台。按高度对平台进行排序。对于每个平台,线性地穿过它下面的所有平台,从最近的平台开始。查看较高平台的x值是否落在下平台边缘定义的范围内。这需要O(P ^ 2)。 (P是平台数量。)
这可能不会直接回答你的问题(也就是说这不是蛮力),但我认为这是指向你的更好的方向。另外,如果你试图强行所有方向,球可以去最终会出现类似O(2 ^ P)的东西,这是一个令人不快的高时间复杂度。