我对这个算法问题有疑问;我将粘贴问题,然后回顾一下我目前的想法和解决方案。
有N (up to 100,000)
线段定义为[(x1, y1), (x2, y2)]
,其中x1 < x2
和y1 < y2
(例如,线段具有正斜率)。没有线段接触或相交,即使在端点处也是如此。第一段有(x1, y1) = (0, 0)
. 将每个部分想象成一个人必须攀登的二维小山。
一个人从第一座山丘开始(0, 0)
并降落。每当一个人降落在山上时,他都会爬到尽头,(x2, y2)
然后直接向下跳。如果他降落在另一座山上(路段上的任何地方),该过程将继续:他爬上那座山并跳跃。如果没有更多的山丘,他就会跌倒-INFINITY
,这个过程就结束了。每个小山(x1, y1) -> (x2, y2)
都应该被看成是含点(x1, y1)
而不是含点(x2,
y2)
,这样人从上面的一个位置跌到山上就着地,从上面x = x1
跌到山上就不会着地。以上在x = x2
。
目标是计算他接触了多少座山。
我现在的想法
我正在考虑沿 x 轴在平面上扫一条线。每个段由一个 BEGIN 和 END 事件组成;每次遇到线段的开头,我们将它添加到一个集合中。每次遇到线段的结尾时,我们都会将其从集合中删除。当我们到达当前山的终点时,我们应该检查我们可以登陆的最高山的集合。但是,我不知道如何确定如何快速检查,因为集合内可能有 N 个条目。另外,跳到另一座山后,这些顺序会改变,因为每个段的坡度可能不同,我不知道如何解释这种差异。
有什么想法吗?