从南到北的折线中,选取尽量少的点建造烽火台,使得敌情可以通过北向南传递到总部,且每一个敌情点能被北方某个烽火台“看到”(没有遮挡)。
设点 A、B、C 从南到北排列,如果你从 C 看向 A,但中间的 B 挡住了视线(因为 B 比连线 AC 更高),那么就说明C → A 不可见,因为 B 遮挡。这个几何问题,本质上就是三点是否形成“凹形”或“右转”。
判断三点 A, B, C 是否构成凹形 —— 用 叉积(cross product)判断转向方向:
叉积公式:
$$ (p2 - p1) \times (p3 - p2) = (x2 - x1) \ast (y3 - y2) - (y2 - y1) \ast (x3 - x2) $$
如果结果 ≥ 0:说明是右转或共线(遮挡)
整体做法是:
- 初始化栈为空。
- 从第一个点(最南端,总部)开始,依次处理每个点。
- 对于当前点,如果前面两个栈顶点 + 当前点构成凹形(即中间点会遮挡),就把中间点从栈中弹出。然后判断栈顶点是否已经是烽火台:如果不是,则现在它必须成为烽火台。
- 最后把当前点压入栈。
代码
1 |
|
赏
使用支付宝打赏
使用微信打赏
若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏