这道题目的大意是,一个人在路边建造了一栋房子,他希望他的房子被路过这条路的人看见。然而在房子和路之间的障碍会阻挡路人的视线。他想要你计算在这条路上,行人能够完整地看到他的房子的最长的一段连续的路段的长度。

路、障碍、房子都被表示成平行于 x 轴的线段,如图:

POJ 2074 示意图

POJ 2074 示意图

原题地址:http://poj.org/problem?id=2074

解题思路

这个题目要注意的地方,就是这些障碍物可能会给在房子的上方、路的下方,并且有的障碍物可能永远挡不住房子,而有的障碍物可能会完全挡住房子。

我的思路是,先把房子和路的信息记下。然后,在读取每个障碍物信息的时候,计算这个障碍物能够挡住路的哪部分。看图:

POJ 2074 一般情况

POJ 2074 一般情况

当然上面那种是一般情况,就是说,那两条绿色的线的交点在路的线段上。如果有特殊情况,交点在路的延长线上,那么就要认为,被挡住的部分是在路的线段相应的端点上。

我写了一个 struct, 记下了每个这种看不见的路段的端点的坐标,并且还记录了一个额外的整数信息。如果这个端点是左端点,那么这个整数是 -1, 反之是 1. 也就是:

然后我弄了一个 vector pfs; 对于每个障碍物,把计算出来的那个看不见的线段的两个端点的 pinfo 存到这个 pfs 里。最后为了方便,我把道路的末端的坐标也放到了 pfs 里,并且道路末端的 i 我设置成了 1.

然后对这个 vector 排序,关键字是端点坐标的 x 值。最后把这个 vector 扫一遍,定义一个临时变量 int fl; 见到一个左端点就 ++fl, 见到一个右端点就 –fl. 如果 fl 是 0 的时候,说明这段路是能够完全看到房子的。

源代码

原创文章,转载请注明来源:http://euyuil.com/2651/poj-2074-line-of-sight/